平常磨刀優化
一、不能被修改的狀況,直接貼代碼講this
//建立一個實體類 public class Demo { private final int info = 123; public int getInfo() { return info; } } //反射修改的代碼區域 public class TestFianl { public static void main(String[] args) { try { test(); } catch (NoSuchFieldException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } } public static void test() throws NoSuchFieldException, IllegalAccessException { Demo demo = new Demo(); System.out.println("反射修改以前 Demo 實例的值:"+demo.getInfo()); Field field = demo.getClass().getDeclaredField("info"); field.setAccessible(true);//靈魂語句 field.set(demo, 789); System.out.println("反射修改以後 Field 實例的值:"+field.get(demo)); System.out.println("反射修改以後 Demo 實例的值:"+demo.getInfo()); } } //輸出結果爲: 反射修改以前 Demo 實例的值:123 反射修改以後 Field 實例的值:789 反射修改以後 Demo 實例的值:123
一、注意這裏的 修改的 成員變量 info 是被基本數據類型 int 修飾的code
二、編譯的時候 被final修飾的成員變量會被優化,全部用到該變量的地方都被替換成了變量的內容 123get
第二句話解釋看如下Demo 類反編譯的代碼io
public class Demo { private final int info = 123; public int getInfo() { return 123;//直接返回了 123 這個內容 而不是 info 這個變量 } }
二、能被修改的狀況編譯
//建立一個實體類 public class Demo { private final Integer info = 123; public Integer getInfo() { return info; } } //反射修改的代碼區域 和 1 中的沒有區別 public class TestFianl { public static void main(String[] args) { try { test(); } catch (NoSuchFieldException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } } public static void test() throws NoSuchFieldException, IllegalAccessException { Demo demo = new Demo(); System.out.println("反射修改以前 Demo 實例的值:"+demo.getInfo()); Field field = demo.getClass().getDeclaredField("info"); field.setAccessible(true);//靈魂語句 field.set(demo, 789); System.out.println("反射修改以後 Field 實例的值:"+field.get(demo)); System.out.println("反射修改以後 Demo 實例的值:"+demo.getInfo()); } } //輸出結果爲: 反射修改以前 Demo 實例的值:123 反射修改以後 Field 實例的值:789 反射修改以後 Demo 實例的值:789
一、注意這裏的 修改的 成員變量 info 是被 包裝類 Integer 修飾的class
二、定義的時候並無初始化值,getInfo方法返回的是info這個變量test
如下Demo 類反編譯的代碼變量
public class Demo { private final Integer info = Integer.valueOf(123);//定義的時候檢查再初始化了值 public Integer getInfo() { return this.info; } }
因此成員變量在定義的時候沒有初始化值的時候,就算用final修飾,同樣能夠被經過反射以後進行修改權限