小论Java类变量的隐私泄露
為什么80%的碼農(nóng)都做不了架構(gòu)師?>>> ??
什么是類(lèi)變量的隱私泄露
在面向?qū)ο缶幊痰倪^(guò)程中,一個(gè)特定的類(lèi)A往往含有一些私有變量。對(duì)于私有變量,我們往往會(huì)設(shè)置其封裝字段為“private”,并且設(shè)置get函數(shù)和set函數(shù),希望其他類(lèi)能且僅通過(guò)類(lèi)A的get函數(shù)和set函數(shù)去更改這些私有變量。
然而,有的時(shí)候,其他類(lèi)B中可能包含了表示A類(lèi)的對(duì)象以及包含了能夠修改A類(lèi)私有屬性的方法,或稱(chēng)B和A構(gòu)成復(fù)合(B has A)關(guān)系,此時(shí),我們?cè)谡{(diào)用類(lèi)B的過(guò)程中就有可能改變類(lèi)A的私有屬性,這就稱(chēng)為“隱私泄露”(privacy leak)。
舉個(gè)栗子
現(xiàn)有一個(gè)“銀行”類(lèi)如下:(A類(lèi))
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并且,我們?cè)O(shè)置了一個(gè)“用戶(hù)”類(lèi)(B類(lèi)),其中含有修改該用戶(hù)密碼的函數(shù):
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 "用戶(hù):" + username + " " + bankAccount;}//end method}//end class我們即可發(fā)現(xiàn),通過(guò)User類(lèi)不僅可以改變與當(dāng)前用戶(hù)相關(guān)賬號(hào)的密碼,還能改變與之不想關(guān)任何包含了的類(lèi)Bank實(shí)例化對(duì)象的密碼,某個(gè)示例代碼如下(C類(lèi)):
public static void main(String[] args) {Bank bankAcc1 = new Bank("銀行初始化賬戶(hù)", "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只是用來(lái)初始化用戶(hù)的,因此“肉雞”用戶(hù)密碼的修改不應(yīng)該連帶修改了銀行類(lèi)對(duì)象bankAcc1中的密碼,更不應(yīng)該改變“傻哥”賬號(hào)的密碼。因此我們說(shuō)bankAcc1由于User類(lèi)對(duì)它的調(diào)用,其私有變量password產(chǎn)生了“隱私泄露”。
解決之道
當(dāng)程序?qū)τ陬?lèi)型安全有特殊要求時(shí)(沒(méi)要求的話(huà)當(dāng)然隨意),我們需要對(duì)于調(diào)用了其他類(lèi)A的類(lèi)B中的函數(shù)做出一定修改,使得其他類(lèi)(C類(lèi))不能通過(guò)修改B類(lèi)的方式修改A類(lèi)的私有變量。其方法就是,我們需要對(duì)于A類(lèi)加一個(gè)“克隆構(gòu)造函數(shù)”(copy constructor)。在B類(lèi)中的函數(shù)對(duì)于代表A類(lèi)的變量進(jìn)行調(diào)用時(shí),首先“克隆”一份A類(lèi)對(duì)象原本的映像,再在映像上進(jìn)行修改,從而使得代表A類(lèi)的對(duì)象屬性不變,而B(niǎo)類(lèi)中相應(yīng)的屬性發(fā)生我們希望的變更。針對(duì)上述的例子,我們需要做如下修改:
“銀行”類(lèi)(A類(lèi))中添加的代碼:
public Bank(Bank orig){this.username = orig.username;this.password = orig.password;}“用戶(hù)”類(lèi)(B類(lèi))變更resetBankPassword函數(shù)如下:
public void resetBankPassword(String newPassword){bankAccount = new Bank(bankAccount);bankAccount.setPassword(newPassword); }//end methodC類(lèi)調(diào)用保持不變,獲得以下結(jié)果:
此時(shí),我們就在成功變更用戶(hù)密碼時(shí)并沒(méi)有改變初始賬號(hào)的密碼,從而實(shí)現(xiàn)了對(duì)初始賬號(hào)私有變量“密碼”的隱私保護(hù)。
注意:
使用copy constructor確實(shí)實(shí)現(xiàn)了對(duì)于無(wú)關(guān)類(lèi)私有變量的隱私保護(hù),然而其實(shí)現(xiàn)過(guò)程中由于“拷貝”了整個(gè)對(duì)象的數(shù)據(jù),因此會(huì)增加額外的內(nèi)存需求,在某個(gè)類(lèi)的對(duì)象包含大量數(shù)據(jù)且對(duì)類(lèi)型安全無(wú)特殊要求時(shí),應(yīng)當(dāng)慎用此招。
參考資料:
[1] W. Savitch, Absolute Java. Pearson Addison Wesley 6th Edition, 2013.
轉(zhuǎn)載于:https://my.oschina.net/Samyan/blog/2874702
總結(jié)
以上是生活随笔為你收集整理的小论Java类变量的隐私泄露的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 数据结构与算法分析-第2章
- 下一篇: 11月12日云栖精选夜读 | 2135亿