小论Java类变量的隐私泄露
為什么80%的碼農都做不了架構師?>>> ??
什么是類變量的隱私泄露
在面向對象編程的過程中,一個特定的類A往往含有一些私有變量。對于私有變量,我們往往會設置其封裝字段為“private”,并且設置get函數和set函數,希望其他類能且僅通過類A的get函數和set函數去更改這些私有變量。
然而,有的時候,其他類B中可能包含了表示A類的對象以及包含了能夠修改A類私有屬性的方法,或稱B和A構成復合(B has A)關系,此時,我們在調用類B的過程中就有可能改變類A的私有屬性,這就稱為“隱私泄露”(privacy leak)。
舉個栗子
現有一個“銀行”類如下:(A類)
public class Bank {private final String username; //Assume username does not change often.private String password;public Bank(String username, String password){this.username = username;this.password = password;}//end constructorpublic void setPassword(String pass){password = pass;}//end method@Overridepublic String toString(){return "Bank: Username: " + username + ", password: " + password;}//end method }//end class并且,我們設置了一個“用戶”類(B類),其中含有修改該用戶密碼的函數:
public class User {private String username;private Bank bankAccount;public User(String username){this(username, null);}//end conspublic User(String username, Bank bank){this.username = username;this.bankAccount = bank;}//end methodpublic void resetBankPassword(String newPassword){bankAccount.setPassword(newPassword);}//end method@Overridepublic String toString(){return "用戶:" + username + " " + bankAccount;}//end method}//end class我們即可發現,通過User類不僅可以改變與當前用戶相關賬號的密碼,還能改變與之不想關任何包含了的類Bank實例化對象的密碼,某個示例代碼如下(C類):
public static void main(String[] args) {Bank bankAcc1 = new Bank("銀行初始化賬戶", "123456");User user1 = new User("肉雞", bankAcc1);User user2 = new User("傻哥", bankAcc1);user1.resetBankPassword("654321");System.out.println(bankAcc1);System.out.println(user1);System.out.println(user2);}//end mainbankAcc1只是用來初始化用戶的,因此“肉雞”用戶密碼的修改不應該連帶修改了銀行類對象bankAcc1中的密碼,更不應該改變“傻哥”賬號的密碼。因此我們說bankAcc1由于User類對它的調用,其私有變量password產生了“隱私泄露”。
解決之道
當程序對于類型安全有特殊要求時(沒要求的話當然隨意),我們需要對于調用了其他類A的類B中的函數做出一定修改,使得其他類(C類)不能通過修改B類的方式修改A類的私有變量。其方法就是,我們需要對于A類加一個“克隆構造函數”(copy constructor)。在B類中的函數對于代表A類的變量進行調用時,首先“克隆”一份A類對象原本的映像,再在映像上進行修改,從而使得代表A類的對象屬性不變,而B類中相應的屬性發生我們希望的變更。針對上述的例子,我們需要做如下修改:
“銀行”類(A類)中添加的代碼:
public Bank(Bank orig){this.username = orig.username;this.password = orig.password;}“用戶”類(B類)變更resetBankPassword函數如下:
public void resetBankPassword(String newPassword){bankAccount = new Bank(bankAccount);bankAccount.setPassword(newPassword); }//end methodC類調用保持不變,獲得以下結果:
此時,我們就在成功變更用戶密碼時并沒有改變初始賬號的密碼,從而實現了對初始賬號私有變量“密碼”的隱私保護。
注意:
使用copy constructor確實實現了對于無關類私有變量的隱私保護,然而其實現過程中由于“拷貝”了整個對象的數據,因此會增加額外的內存需求,在某個類的對象包含大量數據且對類型安全無特殊要求時,應當慎用此招。
參考資料:
[1] W. Savitch, Absolute Java. Pearson Addison Wesley 6th Edition, 2013.
轉載于:https://my.oschina.net/Samyan/blog/2874702
總結
以上是生活随笔為你收集整理的小论Java类变量的隐私泄露的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 数据结构与算法分析-第2章
- 下一篇: 11月12日云栖精选夜读 | 2135亿