final的作用
final根据修饰位置的不同作用也不相同,针对三种情况:
1)修饰变量,被final修饰的变量必须要初始化,赋初值后不能再重新赋值。
注意:局部变量不在我们讨论的范畴,因为局部变量本身就有作用范围,不使用private、public等词修饰。
2)修饰方法,被final修饰的方法代表不能重写。
3)修饰类,被final修饰的类,不能够被继承。
注意:final修饰的类,类中的所有成员方法都被隐式地指定为final方法。
所有的final修饰的字段都是编译期常量吗?
并不是,比如String
如何理解private所修饰的方法是隐式的final?
不太正确,private可以通过反射的方式去修改,final如果通过反射的方式去修改值的话,必须要避开编译的自动优化,例如这样:private final int a=(null!=null?0:1);
Java反射机制可以动态修改实例中final修饰的成员变量吗?
回答是分两种情况的。
-
当final修饰的成员变量在定义的时候就初始化了值,那么java反射机制就已经不能动态修改它的值了。
-
当final修饰的成员变量在定义的时候并没有初始化值的话,那么就还能通过java反射机制来动态修改它的值。
public class MainTest {
public static void main(String[] args) {
try {
A a = new A();
Field field = a.getClass().getDeclaredField("a");
field.setAccessible(true);
field.set(a, 2);
System.out.println(field.get(a)); //打印 2
System.out.println(a.getA()); //打印 1 为什么这里不是2
} catch (SecurityException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
class A {
private final int a=1 ;
public int getA()
{
return this.a;
}
}
如果把A修改为
class A {
private final int a ; //区别在于这里没给a直接赋值,而是用构造函数
public A()
{
this.a=1;
}
public int getA()
{
return this.a;
}
}
System.out.println(field.get(a)); //打印 2
System.out.println(a.getA()); //打印 2 为什么这次是2了
原因在于编译期间final类型的数据自动被优化了,即:所有用到该变量的地方都呗替换成了常量。所以 get方法在编译后自动优化成了return 1 ; 而不是 return this.a;
要想不被自动优化,可以把初始化代码改成:private final int a=(null!=null?0:1);
网友评论