问题:Java反射机制可以动态修改实例中final修饰的成员变量吗?
回答是分两种情况的。
1. 当final修饰的成员变量在定义的时候就初始化了值,那么java反射机制就已经不能动态修改它的值了。
2. 当final修饰的成员变量在定义的时候并没有初始化值的话,那么就还能通过java反射机制来动态修改它的值。
实验:
1. 当final修饰的成员变量在定义的时候就初始化了值
public Class Person {
private final String name = "damon.huang";
public String getName() {
return this.name;
}
}
import java.lang.reflect.Field; /**
* @author damon.huang
*
*/
public class TestReflect { public static void main(final String[] args) {
final Person p = new Person();
System.out.println("原始值:" + p.getName());
System.out.println("--------separate----------");
changePorperty(p);
} public static void changePorperty(final Person p) {
final Class<?> clz = p.getClass();
try {
final Field nameField = clz.getDeclaredField("name");
nameField.setAccessible(true);
nameField.set(p, String.valueOf("huang.damon"));
System.out.println("反射机制修改后的Field实例的值:" + nameField.get(p));
System.out.println("反射机制修改后的Person实例的值:" + p.getName());
System.out.println("--------separate----------");
} catch (final NoSuchFieldException e) {
e.printStackTrace();
} catch (final SecurityException e) {
e.printStackTrace();
} catch (final IllegalArgumentException e) {
e.printStackTrace();
} catch (final IllegalAccessException e) {
e.printStackTrace();
}
}
}
结果如下:
原始值: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修饰的成员变量值被动态修改了