从同一类的不同实例访问私有方法
Posted
技术标签:
【中文标题】从同一类的不同实例访问私有方法【英文标题】:Accessing private method from different instance of the same class 【发布时间】:2017-09-19 05:53:56 【问题描述】:我刚刚遇到一个代码。在一种情况下,我无法使用其实例访问该类的私有成员(这很好),但在另一种情况下,我能够使用其不同的实例访问私有成员(属于同一类)。谁能解释一下为什么会这样?
class Complex
private double re, im;
public String toString()
return "(" + re + " + " + im + "i)";
Complex()
/*Below c is different instance, still it can access re,im( has a private access)
without any error.why? */
Complex(Complex c)
re = c.re;
im = c.im;
public class Main
public static void main(String[] args)
Complex c1 = new Complex();
Complex c2 = new Complex(c1);
System.out.println(c1.re); /* But getting an error here ,
which is expected as re and im has a private access in Complex class.*/
【问题讨论】:
因为Java就是这样工作的? “否则,成员或构造函数被声明为私有,并且当且仅当它出现在包含成员或构造函数声明的***类(第 7.6 节)的主体中时才允许访问。” (JLS 6.6.1) Java 中的访问控制是按类而不是实例。 (诚然,protected 在这方面有点棘手。) 【参考方案1】:您可以从同一类中定义的任何代码块访问私有成员。不管实例是什么,或者是否有任何实例(代码块在静态上下文中)。
但是您不能从不同类中定义的代码访问它们。
您的第一个参考在同一个类中,Complex
,这就是它起作用的原因。而第二个在另一个类中,Main
,这就是它不起作用的原因。
【讨论】:
如果我不希望同一类的不同实例访问该字段,我该怎么做?更清楚地说,我要求的是 Scala 中的private[this]
之类的东西
AFAIK 在 Java 中是不可能的。无论如何,我看不到它的重要性:对我来说,封装是关于代码(及其所有权),而不是运行时实例。【参考方案2】:
原因是Main
类无法访问其他类的私有字段。在这种情况下,Complex
类的私有字段。
您只能从此类中的方法访问 Complex
类中的私有字段。换句话说,如果您将 main
方法移动到 Complex
类,代码将被编译。
如果你想从Main
(或其他类)获取/设置Complex
类中的值,你应该在Complex
类中添加setter/getter。
【讨论】:
【参考方案3】:这是解释访问修饰符的表格:
如您所见,在private
行中,除了Class
列之外,所有内容都是N
。这意味着您可以访问私有成员,只要您在声明它们的同一类中访问它们。您甚至可以使用实例从同一类中的静态上下文访问私有非静态成员。没有访问修饰符只允许从同一个实例进行访问。
为什么?
因为在编译时弄清楚this
和c
是否是同一个实例是一件很痛苦的事情。您必须实际运行代码以查看它们是否引用相同的实例。
【讨论】:
【参考方案4】:从概念上讲,访问说明符是@class 级别,而不是@instance 级别。
以下可能是保持访问说明符@类级别的原因。 从JLS Documentation,我们可以清楚地看到访问是针对用户的,他们正在基于契约实现(或使用类/包)。
简单来说,作为开发人员(用户),我所关心的只是可用的成员(变量、方法)、它们的作用、我如何使用它们(抽象概念的基础)。
在你的情况下,它是同一个类,它拥有访问其成员的所有特权,因此可以观察到的行为。
【讨论】:
以上是关于从同一类的不同实例访问私有方法的主要内容,如果未能解决你的问题,请参考以下文章