编写以下代码时,编译器如何不抱怨?
public class MyClass
{
private int count;
public MyClass(int x){
this.count=x;
}
public void testPrivate(MyClass o){
System.out.println(o.count);
}
}
即使它是写入testPrivate
的同一个类的实例,也不应该在System.out.println(o.count)
处给出编译错误?毕竟,我试图直接访问私人变量
代码甚至运行良好。
答案 0 :(得分:57)
私有成员可以从声明它的类中的任何方法访问,无论该方法是否访问其自己的(this
)实例的私有成员或其他实例的私有成员。
这在JLS 6.6.1中说明:
...否则,如果成员或构造函数被声明为private,则当且仅当它发生在包含成员或构造函数声明的顶级类(第7.6节)的主体内时才允许访问。
Java的这个特性允许您编写接受类实例作为参数的方法(例如 - clone(Object other)
,compareTo(Object other)
),而不依赖于具有非私有getter的类。需要访问的私有属性。
答案 1 :(得分:12)
私有字段作为一个整体是私有的,而不仅仅是对象。
其他类不知道MyClass有一个名为count的字段;但是,MyClass对象知道另一个MyClass对象具有count字段。
答案 2 :(得分:6)
访问者不安全!它们是封装,以防止其他人知道代码。
考虑是否有人写了Quantum Bogo Sort,但是一旦他撤消了最后一个错误就消失了 - 理解代码会导致一个人从宇宙中删除或者发疯。
尽管有这个小缺点,如果正确封装,这应该成为您首选的排序算法,因为除Sort之外的所有字段和方法都应该是私有的。
你不知道它是如何工作的,你不想知道它是如何工作的,但是它的工作原理还不够。另一方面,如果一切都是公开的,你必须了解它如何才能正确使用它 - 这太麻烦了,我会坚持使用quicksort。
答案 3 :(得分:3)
虽然它是testPrivate所在的同一个类的实例 写的,但不应该通过编译错误 的System.out.println(o.count);
否即可。它永远不会抛出编译错误。
这与简单的getter和setter或复制构造函数的作用非常类似。请注意,我们可以使用private
this.
个成员
public MyClass {
private String propertyOne;
private String propertyTwo;
// cannot access otherObject private members directly
// so we use getters
// But MyClass private members are accessible using this.
public MyClass(OtherClass otherObject) {
this.propertyOne = otherObject.getPropertyOne();
this.propertyTwo = otherObject.calculatePropertyTwo();
}
public void setPropertyOne(String propertyOne) {
this.propertyOne = propertyOne;
}
public String getPropertyOne() {
return this.propertyOne;
}
}
您的testPrivate
方法接受MyClass的实例。由于testPrivate
是MyClass
内的方法,因此可以访问private
个属性。
public void testPrivate(MyClass o) {
this.propertyOne = o.propertOne;
}
在课程中定义的方法始终可以通过private
和实例变量访问this.
成员。
但是,如果您在testPrivate
之外定义MyClass
,那么您将无法访问private
个成员。在那里你将不得不使用方法或设定者或吸气剂。
答案 4 :(得分:0)
声明为private的方法,变量和构造函数只能在声明的类本身中访问。查看official documentation