私有成员访问Java

私有成员是在类级别还是在对象级别访问。 如果它在对象级别,则以下代码不应编译

class PrivateMember { private int i; public PrivateMember() { i = 2; } public void printI() { System.out.println("i is: "+i); } public void messWithI(PrivateMember t) { ti *= 2; } public static void main (String args[]) { PrivateMember sub = new PrivateMember(); PrivateMember obj = new PrivateMember(); obj.printI(); sub.messWithI(obj); obj.printI(); } } 

请说明在sub的messWithI()方法中访问obj的成员i是否有效

正如DevSolar所说,它处于(顶级)级别。

从Java语言规范的6.6节 :

否则,如果成员或构造函数被声明为private,则当且仅当它发生在包含成员或构造函数声明的顶级类(第7.6节)的主体内时才允许访问。

请注意,没有迹象表明它仅限于特定对象的成员。

从Java 7开始, 编译器不再允许访问类型变量的私有成员 。 因此,如果该方法具有类似public void messWithI(T t)的签名,则访问ti将是编译器错误。 但是,这不会改变您的特定情况。

请注意,您甚至不需要源级别访问来混乱私有字段。 通过使用java.lang.reflect.AccessibleObject.setAccessibe() ,除非您指定禁止它的安全策略,否则所有代码都可以访问所有其他代码的所有私有成员。

private本身不是一个安全function! 对于其他开发人员而言,这只是一个强有力的提示,即某些内容是代码中其他部分不应依赖的内部实现细节。

都不是。 私有访问的范围限定在封闭的顶级类中,因此您可以在同一顶级类中访问不同类的私有成员:

 class PrivateAccess { static class InnerOne { private int value; } static class InnerTwo { int getOne ( InnerOne other ) { return other.value; } } } 

类访问的通常含义意味着您可以访问相同类型的其他实例的私有。 在Java中,私有访问是通过词法确定的,而不是按类型确定的。

class级。 这个想法是类的代码(但没有别的)知道如何处理该类的对象。

如果您无论如何都可以访问类源代码,那么“隐藏”您的任何内容几乎没有意义。

正如其他人所说,私有的,默认的访问(“包私有”),受保护的,也许在JDK 7模块中是基于类的(嵌套类inheritance有非常奇怪的规则,我不记得了)。 但为什么?

主要是作为二进制(或更多)运算符的方法。 为了有效实现,他们通常需要或更容易编写,而无需使用或修改公共API。 看看equals实现 – 在良好的代码中,您可以找到this进行少量方法调用的字段的直接访问。 (现在的性能方面与现代JVM内联常见调用大多无关,但代码质量问题仍然存在。)

只是为了添加DevSolar的答案,我希望messWithI被声明为静态:

 public static void messWithI(PrivateMember t) { ti *= 2; 

我甚至很难读到你在没有“静态”暗示的情况下尝试做的事情……而且它也更容易回答你原来的问题 – 私人成员的范围不限于只是有问题的实例。

同一页面说,在6.6.8小节中,您还可以找到以下声明:

私有类成员或构造函数只能在包含成员或构造函数声明的顶级类的主体内访问。 它不是由子类inheritance的。

我们在这里评估的私人类成员是i

public void messWithI()是一个存在于声明的顶层类体内的方法,它恰好是PrivateMember

您的构造符合上述声明,这就是它运行没有问题的原因。

Thas是另一种与Jon和Devsolar说同样的方式。

类成员的访问修饰符与编写代码的位置(在哪个包中以及在哪个类中)相关,而不管授予访问权限的成员类型:类成员还是实例成员。

从逻辑上讲,如果没有类的实例,则不能使用类的实例成员,但这是与成员生命周期相关的不同问题。