问题:Java反射机制可以动态修改实例中final修饰的成员变量吗?
回答是分两种情况的。
-
当final修饰的成员变量在定义的时候就初始化了值,那么java反射机制就已经不能动态修改它的值了。
-
当final修饰的成员变量在定义的时候并没有初始化值的话,那么就还能通过java反射机制来动态修改它的值。
-
实验:
1. 当final修饰的成员变量在定义的时候就初始化了值
1 public Class Person {
2 private final String name = "damon.huang";
3 public String getName() {
4 return this.name;
5 }
6 }
1 import java.lang.reflect.Field;
2
3 /**
4 * @author damon.huang
5 *
6 */
7 public class TestReflect {
8
9 public static void main(final String[] args) {
10 final Person p = new Person();
11 System.out.println("原始值:" + p.getName());
12 System.out.println("--------separate----------");
13 changePorperty(p);
14 }
15
16 public static void changePorperty(final Person p) {
17 final Class<?> clz = p.getClass();
18 try {
19 final Field nameField = clz.getDeclaredField("name");
20 nameField.setAccessible(true);
21 nameField.set(p, String.valueOf("huang.damon"));
22 System.out.println("反射机制修改后的Field实例的值:" + nameField.get(p));
23 System.out.println("反射机制修改后的Person实例的值:" + p.getName());
24 System.out.println("--------separate----------");
25 } catch (final NoSuchFieldException e) {
26 e.printStackTrace();
27 } catch (final SecurityException e) {
28 e.printStackTrace();
29 } catch (final IllegalArgumentException e) {
30 e.printStackTrace();
31 } catch (final IllegalAccessException e) {
32 e.printStackTrace();
33 }
34 }
35 }
结果如下:
原始值:damon.huang
--------separate----------
反射机制修改后的Field实例的值nameField.get(p):huang.damon
反射机制修改后的Person实例的值p.getName():damon.huang
--------separate----------
为什么p.getName()的值没有被修改掉呢,这是因为
编译期间final类型的数据自动被优化了,即:所有用到该变量的地方都被替换成了常量。所以 get方法在编译后自动优化成了return “damon.huang”; 而不是 return this.name;
可以通过String name = (null!=null?“ddd”:“damon.huang”);来阻止编译时的自动优化。refere to: 答案引用这是的结果就会看到变量值被动态修改了
原始值:damon.huang
--------separate----------
反射机制修改后的Field实例的值:huang.damon
反射机制修改后的Person实例的值:huang.damon
--------separate----------
2.当final修饰的成员变量在定义的时候并没有初始化值的话
public class Person {
private final String name;
public Person() {
this.name = "damon.huang";
}
public String getName() {
return this.name;
}
}
原始值:damon.huang
--------separate----------
反射机制修改后的Field实例的值:huang.damon
反射机制修改后的Person实例的值:huang.damon
--------separate----------
结果是final修饰的成员变量值被动态修改了