zoukankan      html  css  js  c++  java
  • Java反射机制可以动态修改实例中final修饰的成员变量吗?

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

    回答是分两种情况的。

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

    2. 当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修饰的成员变量在定义的时候并没有初始化值的话

     1 public class Person {
     2     private final String name;
     3 
     4     public Person() {
     5         this.name = "damon.huang";
     6     }
     7 
     8     public String getName() {
     9         return this.name;
    10     }
    11 }
    原始值:damon.huang
    --------separate----------
    反射机制修改后的Field实例的值:huang.damon
    反射机制修改后的Person实例的值:huang.damon
    --------separate----------

    结果是final修饰的成员变量值被动态修改了

  • 相关阅读:
    1. shiro-用户认证
    Salt 盐值
    使用ajax向后台发送请求跳转页面无效的原因
    @RequestParam和@RequestBody的区别
    JavaSE:Java11的新特性
    JavaSE: Java10的新特性
    JavaSE:Java9 新特性
    JavaSE:Java8新特性
    JavaSE:Java8新特性
    JavaSE:Java8 新特性
  • 原文地址:https://www.cnblogs.com/damonhuang/p/5421563.html
Copyright © 2011-2022 走看看