1.final数据
指编译时常量,或者一旦赋值就不允许被改变的数据。如果是编译时常量,就要用static和final修饰,常量名大写,单词与单词之间用_隔开。final数据必须是基本数据类型。
private static final int MAX_VALUE = 15;
2.final引用
如果final修饰的是一个对象,它并不是指对象是不可变的,而是存储对象的内存地址是不可变的
public void timerTask() { final TestA t = new TestA(); t.setName("liyc"); System.out.println(t.getName()); t.setName("gzslyc333"); System.out.println(t.getName()); }
尽管t是被final修饰,但是t内部的属性是完全可以改变的。
3.空白final
空白final指允许在一个类中存在没有被赋值的final域,但该域必须在被使用前完成初始化,所以空白final一般在构造方法中完成初始化。
class TT{ private final String name; public TT(String str) { this.name = str; } }
这样的优势是方便动态的指定final数据。
4.final参数
final参数通常在匿名内部类中使用,参数在方法中不允许再重新赋值
public TT get(final String number) { return new TT() { public void say() { //number = "555";错误,静态参数接收外部值后不允许重新赋值 System.out.println(number); } }; }同时结合final数据和final引用,如果final参数是基本数据类型,那么它一旦被赋值就不允许被改变。我们可以把final参数当作原数据的一个副本,所以哪怕方法体外原数据怎么改变,方法体内final参数都不会发生改变。比如
public class TestTimer { public void timerTask() { int a = 666; TT t = new TT().get(a); t.say(); a=555; t.say(); } } class TT{ public void say() {} public TT get(final int number) { return new TT() { public void say() { //number = "555";错误,静态参数接收外部值后不允许重新赋值 System.out.println(number); } }; } }
根据上面的结论,我们可以知道输出结果为666和666,而非666和555。
那么同理,如果final参数是一个对象,它只是指存储对象的地址不变而已,对象内部是可以变化的,方法体内部也会随着对象改变而改变,比如
public class TestTimer { public void timerTask() { TestA test = new TestA(); test.setName("55开"); TT t = new TT().get(test); t.say(); test.setName("pdd"); t.say(); } } class TT{ public void say() {} public TT get(final TestA t) { return new TT() { public void say() { //number = "555";错误,静态参数接收外部值后不允许重新赋值 System.out.println(t.getName()); } }; } }
这次的输出结果为55开和pdd了。
5.final方法
final方法指不可以被重写的方法。
6.final类
指不可以被继承的类。但是final类中的域可以根据自己的意愿设定它们是否为final,不过方法则都是隐式声明为final的,毕竟final类不可以被继承,其中的方法自然也不能被重写了。