final的三种用法
修饰变量、方法、类
1.修饰变量
一旦赋值不能修改
为什么?
- 设计角度:更清晰,不容易出错
- 线程安全:不可变的对象是线程安全的,不需要我们额外进项同步处理,这些开销是没有的,如果final修饰的是基本数据类型,那么它具备了不可变这个性质,所以自动保证了线程安全
赋值时机
-
成员变量,类中非static
-
public class a{ private final int finalVar=0; } -
public class a{ private final int finalVar; public a(){ finalVar=0; } } -
public class a{ private final int finalVar; { finalVar=0; } } -
必须赋值
-
空白final:如果我们声明了 final 变量之后,并没有立刻在等号右侧对它赋值, 这种情况就被称为 “空白 final”。这样做的好处在于增加了 final 变量的灵活性,比如可以在构造函数中 根据不同的情况,对 final 变量进行不同的赋值,这样的话,被 final 修饰的变量就不会变得死板,同时 又能保证在赋值后保持不变。我们用下面这个代码来说明:
-
public class BlankFinal { //灵活 private final int a; public BlankFinal() { this.a = 0; } public BlankFinal(int a) { this.a = a; } }在这个代码中,我们有一个 private final 的 int 变量叫作 a,该类有两个构造函数,第一个构造函数是把 a 赋值为 0,第二个构造函数是把 a 赋值为传进来的参数,所以你调用不同的构造函数,就会有不同的赋值情况。这样一来,利用这个规则,我们就可以根据业务去给 final 变量设计更灵活的赋值逻辑。 所以利用空白 final 的一大好处,就是可以让这个 final 变量的值并不是说非常死板,不是绝对固定的,而是可以根据情况进行灵活的赋值,只不过一旦赋值后,就不能再更改了。
-
-
-
静态变量
- 2种
-
public class StaticFieldAssignment1 { private static final int a = 0; } -
public class StaticFieldAssignment1 { private static final int a; static { a = 0; } } - 注意:static 的 final 变量不能在构造函数中进行赋值。
-
局部变量
-
1种:在使用之前必须对它进行赋值
-
public class LocalVarAssignment1 { public void foo() { final int a = 0; } } class LocalVarAssignment2 { public void foo() { final int a; } } class LocalVarAssignment3 { public void foo() { final int a; a = 0; System.out.println(a); } } -
特殊用法:final修饰参数
-
public class FinalPara { public static void withFinal(final int a) { System.out.println(a); } }
-
-
2.修饰方法
-
提高效率,因为Java版本中会把final方法转为内嵌使用,可以消除方法调用的开销,提高程序运行效率,不过后期Java版本JVM会对此自动进行优化,不需要程序员使用final修饰方法进行这些优化,即使使用也不会有性能提升
-
把这个方法锁定,任何继承类补鞥呢修改这个方法含义,不可以被重写
-
构造方法不允许被final修饰
-
注意:final的private方法,其他范围修饰符根本不能用
-
public class PrivateFinalMethod { private final void privateEat() { } } class SubClass2 extends PrivateFinalMethod { private final void privateEat() { } }这不是真正重写,只是方法名碰巧相同,加上@Override就报错
-
3.修饰类
- 不允许其他人继承,保证线程安全
- 给某个类加上了 final 关键字,这并不代表里面的成员变量自动被加上final。事实上,这两者之间不存在相互影响的关系,也就是说,类是 final 的,不代表里面的属性就会自动加上 final。
- 其实在 final 的类里面,所有的方法,不论是 public、private 还是其他权限修饰符修饰的,都会自动的、隐式的被指定为是 final修饰的。
4.如果必须使用final方法或类,请说明原因
未来代码维护者可能不理解为什么这里使用final,使用后是有影响的,把final应用在更小范围的类或方法上,更小的影响
\