Java反射机制可以动态修改实例中final修饰的成员变量吗?

问题:Java反射机制可以动态修改实例中final修饰的成员变量吗?

回答是分两种情况的。

  1. 当final修饰的成员变量在定义的时候就初始化了值,那么java反射机制就已经不能动态修改它的值了。

  2. 当final修饰的成员变量在定义的时候并没有初始化值的话,那么就还能通过java反射机制来动态修改它的值。

  3. 实验:

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修饰的成员变量值被动态修改了

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值