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修飾的成員變量值被動態修改了

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM