final关键字可以修饰类、方法、变量,具体如下:
1、被final修饰的类不可以被继承;
2、被final修饰的方法不可以被重写;
3、被final修饰的变量不可以被再次赋值;
说到第3点这里稍微多说个case,比如通过反射机制能否修改final字段呢?这个问题还是要分情况看的,如下:
情况1
class Obj {
private final int a = 1;
private final String b = "hello";
public int getA() { return a;}
public String getB() { return b; }
}
类似这样的代码,final关键字作用在基本数据类型或者字符串身上,那么在运行时,通过反射机制是无法修改a或者b
的值的,原因是对这种情况下的getXXX方法,编译器做了优化,直接替换成了常量内容,即上面的getA()
方法实际变成了如下的代码:
public int getA() { return 1; }
所以,你通过反射对字段的修改,无法通过getA()
方法体现出来;
情况2
class Obj {
private final int a; // 注意这里,只是声明没有同时赋值(即初始化)
private final String b = "hello";
public Obj() { a = 1; // 直到构造器里才赋值了 }
public int getA() { return a;}
public String getB() { return b; }
}
即a
字段在final定义的时候没有赋值,而是在ctor
里才进行了赋值,那么此种情况下通过反射是可以修改a的值的,原因是此种情况下编译器不会进行情况1里的优化处理,所以getA()
方法,返回的还是对a
字段的引用。
情况3
class Obj {
private final Integer a=1; // 注意这里a是Integer引用类型,而非原生类型
public int getA() { return a;}
}
即使这里字段a
在定义的时候就已经赋值了,但由于其是引用类型,而非基本数据类型,所以运行时通过反射当然是可以修改的。
网友评论