1. java的权限控制--大部分人都被错误洗脑了。
一个重大的坑,或者一个重大的误区,或者说一个洗脑了成千上万java编程者的错误概念就是:
public private protected 是基于方法和对象的。
比如说,private修饰的东西,对象不能访问,但是类中的方法可以访问。
比如说,public修饰的东西,对象和类中的方法都可以访问。
上面简直是误人子弟,你可以把这个概念全部当作垃圾回收了。
2.正解是什么?
我们先来讲 public 和 private ,请看一篇文章中截取的一部分:
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中的每个成员(member)都有一个访问控制修饰符:public,private,protected,或者啥也不写,就是默认。这个访问控制修饰符就决定了“这个成员能被访问到的坏境”。
假设有个类c,属于一个包p,c中有一个成员m。
如果m是public的,注意了,看清了后面这一句:“m就能被任何类中的代码访问”。【看清英文中的 by(code in) 】.
如果m是private的,“m就只能被c类中的代码访问”。
默认情况下,后面也讲了,如果m是默认,就是啥也不写,在本包内部,相当于public。
好,贴一段代码,让你明白这种说法是啥意思:
class C{ private int a; public void printa(C c){ System.out.println(c.a); } }
上面的代码,我很明显访问了,C类中的a变量。而且是通过c.a这种方式访问的,也就是“洗脑观点中的[通过对象访问]”,照“洗脑观点”来说,这一句就是编译不通过了。
然而,这一句很明显,没啥错,为啥。你照正解去解读:
我访问的环境是在哪?在C类中,意思就是说,我这句代码出现在C类中,记得上面的【by code in】么?。这样当然可以访问C类的a。【你甭管是哪个对象的a,跟具体对象无关系】【你甭管是哪个对象的a,跟具体对象无关系】【你甭管是哪个对象的a,跟具体对象无关系】重要的事说三遍。
3.再来讲复杂一点的 protected。
还是先搬英文:
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的,情况就略微复杂了呢。
第一,m可以被本包中的其他类随意访问,注意,我们说类的时候,你一定要加一句,by code in,来反洗脑。也就是说,m可以被本包中任意类的代码访问。
下面这个写的复杂了,我简化一下说法,画个图:
假设p是包名,k是包名,也就是说,不是一个包。
s继承自c。
那么s类中的代码想要访问m,有一个限制:
O必须是s或者s的子类类型。
也就是英文中的o ≤ s。
这样做的原因是,自己去想吧。。。。。。。
或者你可以自己找一下这篇文章:
Checking Access to Protected Members in the Java Virtual Machine
。