摘要:內容簡介利用反射機制修改類中的修飾的變量當然,在沒有提供的情況下。利用反射機制破壞單例模式正文首先,我們有一個包含類型變量的類。所以我們做以下修改新增的代碼于是輸出的結果如下至此,我們已經成功的修改了類中的變量的內容。
內容簡介
利用反射機制修改類中的private修飾的變量(當然,在沒有提供setter的情況下)。
本篇主要講述了如何利用反射機制修改類中的一個private變量。下一篇將會展示利用反射機制來違反或者說攻擊單例模式。
利用反射機制破壞單例模式
首先,我們有一個包含private類型變量的類。
public class PrivateTest { private int privateInt = 0; int getPrivateInt() { return this.privateInt; } }
這里提供了get方法,用于我們后來的檢測。
ok,現在用于測試的類有了,我們來利用反射的機制嘗試修改PrivateTest類中的privateInt變量。
如果我們寫成這樣:
import java.lang.reflect.Field; public class Test { public static void main(String args[]) { PrivateTest privateTest = new PrivateTest(); System.out.println("Before :" + privateTest.getPrivateInt()); Class pClass = privateTest.getClass(); try { Field field = pClass.getDeclaredField("privateInt"); field.set(privateTest, 3); } catch (Exception e) { e.printStackTrace(); } System.out.println("After :" +privateTest.getPrivateInt()); } }
運行之后會發現輸出如下:
Before :0 java.lang.IllegalAccessException: Class Test can not access a member of class PrivateTest with modifiers "private" at sun.reflect.Reflection.ensureMemberAccess(Unknown Source) at java.lang.reflect.Field.doSecurityCheck(Unknown Source) at java.lang.reflect.Field.getFieldAccessor(Unknown Source) at java.lang.reflect.Field.set(Unknown Source) at Test.main(Test.java:17) After :0
也就是說修改失敗了,原因很明顯,因為變量是private的。所以我們做以下修改:
import java.lang.reflect.Field; public class Test { public static void main(String args[]) { PrivateTest privateTest = new PrivateTest(); System.out.println("Before :" + privateTest.getPrivateInt()); Class pClass = privateTest.getClass(); try { Field field = pClass.getDeclaredField("privateInt"); field.setAccessible(true);//新增的代碼 field.set(privateTest, 3); } catch (Exception e) { e.printStackTrace(); } System.out.println("After :" +privateTest.getPrivateInt()); } }
于是輸出的結果如下:
Before :0 After :3
至此,我們已經成功的修改了類中的private變量的內容。
思考到這里的時候我很好奇為什么java會允許這種事情的存在,這種setAccessible的行為是不是破壞了java的封裝性呢?
下一篇要寫的更是利用反射機制成功的破壞掉了單例模式。
剛剛接觸反射和單例,大家多多討論吧!
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/64511.html
摘要:之前利用反射也是改變了類中的變量。單例模式的類測試類這個類中我打印了和的用來驗證是不是同一個對象。利用反射機制破壞單例模式單例模式的類仍然不變。 簡介 利用反射機制破壞了單例模式,這里以懶漢單例模式為例子進行操作。之前利用反射也是改變了類中的private變量。類中的private變量真的private么? 正常的單例模式的實現 這里采用了懶漢的單例模式,順帶說一句我自己對懶漢餓漢的理...
摘要:同樣,用類型的變量來保存這些值也不是線程安全的。僅保證可見性,無法保證線程安全性。并且返回的結果是對象,是局部變量,并未使對象逸出,所以這里也是線程安全的。 《Java并發編程實戰》第3章原文 《Java并發編程實戰》中3.4.2 示例:使用Volatile類型來發布不可變對象 在前面的UnsafeCachingFactorizer類中,我們嘗試用兩個AtomicReferences變...
摘要:如果里調用了一個成員方法,這個方法被子類了,當初始化一個子類實例時,父類的構造函數被的調用,此時父類構造函數的上下文里調用的成員方法,是父類的實現還是子類的實現你能不用運行代碼,就能準確說出這些語句會打印什么出來呢測試測試結果測試 如果constructor里調用了一個成員方法,這個方法被子類override了,當初始化一個子類實例時,父類的構造函數被的調用,此時父類構造函數的上下文里...
摘要:如果里調用了一個成員方法,這個方法被子類了,當初始化一個子類實例時,父類的構造函數被的調用,此時父類構造函數的上下文里調用的成員方法,是父類的實現還是子類的實現你能不用運行代碼,就能準確說出這些語句會打印什么出來呢測試測試結果測試 如果constructor里調用了一個成員方法,這個方法被子類override了,當初始化一個子類實例時,父類的構造函數被的調用,此時父類構造函數的上下文里...
閱讀 1107·2021-11-23 10:05
閱讀 1785·2021-11-12 10:36
閱讀 1853·2019-08-30 15:56
閱讀 1685·2019-08-29 12:32
閱讀 3043·2019-08-28 18:04
閱讀 3428·2019-08-26 12:17
閱讀 2502·2019-08-26 11:35
閱讀 1240·2019-08-23 15:11