Skip to content

final关键字

1171字约4分钟

java

2024-10-24

final关键字

可以修饰的东西:类、方法、变量(类不可被继承、方法不可被重载、成员变量不可被再次赋值)

1.修饰类时:类不能被继承(会隐式给类的方法添加final修饰符)

// 报错,final修饰的类不可继承
public class FinalSub extends FinalClass {
	
}
final class FinalClass{
	
}
public class FinalSub extends FinalTest {
	FinalTest finalTest = new FinalTest();
	// 报错,被final修饰的方法不可重写
	public void test() {
		
	}
	public static void main(String[] args) {
		System.out.println(System.currentTimeMillis());
	}
	
}

作用:防止篡改(重写某些方法)

2.final修饰方法时:方法不可被重写

作用:1.防止重写(防止改变实现)

2.效率问题:当方法体比较短时,final修饰的方法调用时相当于把方法体移动到调用处

// final修饰的方法
public final static void test1() {
    System.out.println("final test1()");
  }
// 普通方法
  public  static void test2() {
  	System.out.println("test2()");
  }

 public static void main(String[] args) {
    System.out.println("非final的方法");
     // 获取jvm的启动时间
    long start = System.currentTimeMillis();
    test2();
    long end = System.currentTimeMillis();
    System.out.println();
    System.out.println(end-start);
    System.out.println("final的方法");
    start = System.currentTimeMillis();
    test1();
    end = System.currentTimeMillis();
    System.out.println();
    System.out.println(end-start); 
  }

Tip:

System.currentTimeMillis()// 获取jvm启动时间(毫秒)

3.final修饰变量:变量为不可变变量

可修饰变量类型:成员变量、局部变量、形参、块变量

final修饰的变量的初始化方式:

1.定义时初始化

private final int i = 0;  // 定义时对不可变变量初始化

2.代码块初始化

private final int a;
{
	a = 4;  // 普通代码块对不可变变量初始化
}

3.构造方法初始化

public class FinalTest {
	private final int j;
	public FinalTest() {
		j = 3;  // 构造方法对不可变变量初始化
	}
}

final+static修饰的变量(常量)的初始化:

1.定义时初始化

private static final int b = 0;  // 定义时对常量初始化

2.static代码块初始化

private static final int c;
static {
	c = 5;  // static代码块对常量初始化
}

作用:

1.限制变量初始化后只能读取,不会被无意间修改

2.效率,促使变量在编译过程被优化从而提高效率

Tip:

javap -c -l 类名.class// 反编译class文件

final修饰引用类型的变量时只是限制不可改变对象的指向,而对象的内容仍然可以改变

abstract关键字

可以修饰的东西:修饰类表示该类是一个抽象类、修饰方法表示该方法是一个抽象方法(没有方法体)

注:abstract不可修饰变量只能修饰类和方法

1.修饰类:

抽象类和普通类的区别:

唯一区别:抽象类不可实例化

final和abstract不能同时出现(同时修饰一个方法或类)

抽象类可以有成员变量、构造方法、成员方法、代码块、内部类、注解

它的成员和普通类没有区别

2.修饰方法

抽象方法没有方法体

public abstract void test(); // 抽象方法没有方法体

一个不能被重写的方法坚决不能被抽象

抽象方法就是用来被重写的

abstract不能与final、static连用

abstract不可以与private连用,原因是private方法不能被继承,不能构成重写操作

抽象类中可以有普通方法

抽象方法必须在抽象类中,抽象方法没有实现,若实例化后将产生一个不能执行的方法,需要限制它不能实例化

public /*final*/ abstract class AbstractTest {// 抽象类不能被final修饰
	// 抽象类可以有成员变量
	private int test;
	public int test1;
//	public abstract int test1;	abstract不能修饰变量
	public abstract void test(); // 抽象方法没有方法体
//	private abstract void test2(); abstract不能与private联用
//	public static abstract void test3(); abstract不能与static联用
//	public final abstract void test4(); abstract不能与final联用
	public abstract void test5();
	// 抽象类可以有普通成员方法
	public void test1() {
		System.out.println("test1()");
	}
}
public class AbstractSub extends AbstractTest {
	@Override
	// 重写抽象类的抽象方法
	public void test() {
		System.out.println("test()");
	}
	@Override
	public void test5() {
		System.out.println("test5()");
	}
	// abstract修饰的类的成员方法可以被子类调用
	public void test7() {
//		new AbstractSub().test1 = 1;
		new AbstractSub().test1();
	}
	// 抽象方法只能在抽象类中
//	public abstract void test6();
}

抽象类的作用:

1.定义规则规范

2.本身不能被实例化但表达了共同的能力

一个类如果继承了抽象方法:

1.重写抽象方法

2.自身继续抽象

自身不可实例化但是可以实例化它的非抽象子类

注:抽象类通常在设计阶段使用,用来规范开发