微信公众号:Java随笔录
关注可了解更多Java相关的技术分享。问题或建议,欢迎公众号留言!
如果你觉得JiangNanMax对你有帮助,欢迎赞赏!
前言
虽然final只是个关键字,但不能不理解其特点,因为在Java开发岗的面试中很有可能提及,而且在实际中代码开发中也会经常使用该关键字。
final关键字的使用还是有不少细节性内容的,使用它的原因,以及带来的效果等。顾名思义,被final关键字修饰的变量是不能变化的,而初衷往往是后续开发的行为限制或者系统性能的优化策略。能使用final关键字进行修饰的内容包括:
- 变量
- 方法
- 类
上述内容,使用final关键字进行修饰后,带来的效果是不一样的?听小录慢慢道来:
使用final修饰变量
变量使用final进行修饰后,必须在被使用前进行初始化,要么在变量定义时进行赋值,要么在构造函数中进行赋值,如此才能通过编译。其中,变量有基本类型和引用类型,在使用final进行修饰时,带来的效果是不一样的:
基本数据类型
public class FinalTest {
private final int X;
private final int Y = 2;
private final int Z = new Random().nextInt();
public FinalTest() {
this.X = 1;
}
public FinalTest(int x) {
this.X = x;
}
}
使用final修饰变量,编译器会在编译期间就将常量值代入相应的计算表达式中,在编译层面上进行了优化。举个例子,int tmp = 3 * Y; 编译后相当于 int tmp = 6;
变量在被final修饰后,其常数值不一定在编译时就确定。可以看到上面的变量Z,它的值只有在运行时,右值进行初始后时才会被赋予。
引用类型
引用类型被final修饰时,它被初始化指向一个对象地址后,就不能修改为指向其他对象,不过,它所指向的对象内容,是可以进行修改的。
public class FinalTest {
private final Obj obj =new Obj();
public Obj change(){
obj.set("222");
return obj;
}
public Obj referToNewObj(){
obj = new Obj();
return obj;
}
class Obj {
private String s = "111";
public String get() {
return s;
}
public void set(String s) {
this.s = s;
}
}
}
上述代码无法编译通过,会提示Cannot assign a value to final variable 'd'
,不过删掉referToNewObj方法,编译运行,可以通过调用change()方法来改变obj对象的s变量值。
使用final修饰方法
- 为什么使用final修饰方法
-
设计:把方法锁定,防止继承类修改它的含义。
-
效率:早期编译器会将final方法所有的调用转为内嵌调用,不过随着JVM的优化,这种方式已被丢弃。
- final和private
当一个方法被private修饰,这会隐式的指定为final,这也会使得子类无法覆盖此方法,可以对private方法增加final修饰,但对该方法并不能增加任何意义。
使用final修饰类
String类是final应用的典型例子
- 为什么要把类指定为final?
出于安全考虑或其他原因,你不希望该类有任何变动或被继承。
一旦类被final修饰,即代表final类中的所有成员变量和方法都会被隐式的final修饰
使用final修饰参数
在方法的参数列表中将参数指定为final,即代表该参数引用所指向的对象是无法改变的;
若为基本类型,则表示值可以读取,但无法修改。修饰情况和final常量类似。
公众号
- 关注公众号,即时接收关于Java的技术分享!
赞赏
- 如果你觉得JiangNanMax对你有帮助,欢迎赞赏,有你的支持,JiangNanMax一定会更加努力!