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