一個(gè)重大的坑,或者一個(gè)重大的誤區(qū),或者說(shuō)一個(gè)洗腦了成千上萬(wàn)java編程者的錯(cuò)誤概念就是:
public PRivate protected 是基于方法和對(duì)象的。
比如說(shuō),private修飾的東西,對(duì)象不能訪(fǎng)問(wèn),但是類(lèi)中的方法可以訪(fǎng)問(wèn)。
比如說(shuō),public修飾的東西,對(duì)象和類(lèi)中的方法都可以訪(fǎng)問(wèn)。
上面簡(jiǎn)直是誤人子弟,你可以把這個(gè)概念全部當(dāng)作垃圾回收了。
我們先來(lái)講 public 和 private ,請(qǐng)看一篇文章中截取的一部分:
In the JVM, like in Java, every member has an associated access attribute: public, private, protected, or default. The attribute determines the circumstances in which the member can be accessed. Let m be a member declared in a class c that belongs to a package p. If m is public, it can be accessed by (code in) any class. If m is private, it can be accessed only by c. If m has default access, it can be accessed only by any class that belongs to p.
好,我大致翻譯一下:
java中的每個(gè)成員(member)都有一個(gè)訪(fǎng)問(wèn)控制修飾符:public,private,protected,或者啥也不寫(xiě),就是默認(rèn)。這個(gè)訪(fǎng)問(wèn)控制修飾符就決定了“這個(gè)成員能被訪(fǎng)問(wèn)到的壞境”。
假設(shè)有個(gè)類(lèi)c,屬于一個(gè)包p,c中有一個(gè)成員m。
如果m是public的,注意了,看清了后面這一句:“m就能被任何類(lèi)中的代碼訪(fǎng)問(wèn)”。【看清英文中的 by(code in) 】.
如果m是private的,“m就只能被c類(lèi)中的代碼訪(fǎng)問(wèn)”。
默認(rèn)情況下,后面也講了,如果m是默認(rèn),就是啥也不寫(xiě),在本包內(nèi)部,相當(dāng)于public。
好,貼一段代碼,讓你明白這種說(shuō)法是啥意思:
class C{ private int a; public void printa(C c){ System.out.println(c.a); }}
上面的代碼,我很明顯訪(fǎng)問(wèn)了,C類(lèi)中的a變量。而且是通過(guò)c.a這種方式訪(fǎng)問(wèn)的,也就是“洗腦觀點(diǎn)中的[通過(guò)對(duì)象訪(fǎng)問(wèn)]”,照“洗腦觀點(diǎn)”來(lái)說(shuō),這一句就是編譯不通過(guò)了。
然而,這一句很明顯,沒(méi)啥錯(cuò),為啥。你照正解去解讀:
我訪(fǎng)問(wèn)的環(huán)境是在哪?在C類(lèi)中,意思就是說(shuō),我這句代碼出現(xiàn)在C類(lèi)中,記得上面的【by code in】么?。這樣當(dāng)然可以訪(fǎng)問(wèn)C類(lèi)的a。【你甭管是哪個(gè)對(duì)象的a,跟具體對(duì)象無(wú)關(guān)系】【你甭管是哪個(gè)對(duì)象的a,跟具體對(duì)象無(wú)關(guān)系】【你甭管是哪個(gè)對(duì)象的a,跟具體對(duì)象無(wú)關(guān)系】重要的事說(shuō)三遍。
還是先搬英文:
If m is protected, things are slightly more complicated. First, m can be accessed by any class belonging to p, as if it had default access. In addition, it can be accessed by any subclass s of c that belongs to a package different from p, with the following restriction: if m is not static, then the class o of the object whose member is being accessed must be s or a subclass of s, written o ≤ s (if m is static, the restriction does not apply: m can be always accessed by s). The relationship among c, s, o, m, and p is depicted in Figure 1, where the double-line arrow labeled by + denotes one or more direct superclasses and the double-line arrow labeled by ∗ denotes zero or more direct superclasses.
好,我還是先翻譯:
如果m是protected的,情況就略微復(fù)雜了呢。
第一,m可以被本包中的其他類(lèi)隨意訪(fǎng)問(wèn),注意,我們說(shuō)類(lèi)的時(shí)候,你一定要加一句,by code in,來(lái)反洗腦。也就是說(shuō),m可以被本包中任意類(lèi)的代碼訪(fǎng)問(wèn)。
下面這個(gè)寫(xiě)的復(fù)雜了,我簡(jiǎn)化一下說(shuō)法,畫(huà)個(gè)圖:

假設(shè)p是包名,k是包名,也就是說(shuō),不是一個(gè)包。
s繼承自c。
那么s類(lèi)中的代碼想要訪(fǎng)問(wèn)m,有一個(gè)限制:
O必須是s或者s的子類(lèi)類(lèi)型。
也就是英文中的o ≤ s。
這樣做的原因是,自己去想吧。。。。。。。
或者你可以自己找一下這篇文章:
Checking Access to Protected Members in the Java Virtual Machine
。
新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注