【问题标题】:Java's private field access [duplicate]Java的私有字段访问[重复]
【发布时间】:2014-04-05 19:56:30
【问题描述】:

我很难理解为什么我可以访问 this. 上下文之外的私有字段? 为了澄清,我添加了一个小的 MyClass 示例:

public class MyClass {

    private int myPrivateInt;

    public MyClass(int myPrivateInt) {
        this.myPrivateInt = myPrivateInt;
    }

    public boolean equals(Object obj) {
        // if it's not an instance of MyClass it's obviously not equal
        if (!(obj instanceof MyClass)) return false;
        MyClass myClass = (MyClass) obj;

        // here comes the part I don't quite understand fully:
        // why can I access a private field outside of the "this." context?
        return this.myPrivateInt == myClass.myPrivateInt;
    }
}

这是一种经过深思熟虑的语言选择,还是根本无法区分 this. 上下文和(或多或少)传递给 equals(对象 obj) 方法?

非常感谢您!

【问题讨论】:

    标签: java


    【解决方案1】:

    您误解了private 的含义。它不限制对this 的访问,它限制对MyClass任何 代码的访问。所以MyClass 中的任何东西都可以访问它,即使它来自MyClass 的不同实例。

    您将无法MyClass 之外访问它,例如:

    public class MyClass {
    
        private int myPrivateInt;
    
        public void example (MyClass m) {
            int x = m.myPrivateInt; // <- OK, we are in MyClass 
        }        
    
    }
    
    public class SomewhereElse {
    
        public void example (MyClass m) {
            int x = m.myPrivateInt; // <- not allowed
        }
    
    }
    

    【讨论】:

    • 好的,我想我已经掌握了它。但是话又说回来,像这样使用它是一种好习惯,还是与 getter 和 setter 一起使用会更好?
    • @baeda 那真的取决于你的情况。使用 getter 允许子类覆盖非最终的 getter,并且在某些情况下这很有帮助。当所讨论的值可能需要一些计算才能获得时,Getter 也很有用。但是对于您的基本示例,使用该私有 int 似乎就足够了。通常,良好的做法是使用任何能产生最清晰、最干净、最可维护的代码以满足您的要求的方法。作为一个练习,尝试编写一个带有 getter 的版本和一个没有 getter 的版本,看看哪个效果更好。这是 cmets 需要回答的一个大问题。
    • 好的,会的。感谢您的时间和回答!
    【解决方案2】:

    很简单,你首先检查你收到的对象是MyClass 类型

    通过以下检查

    obj instanceof MyClass
    

    如果是,您正在检查该对象是否具有与MyClass 相同的属性值,方法是检查以下内容

    this.myPrivateInt == myClass.myPrivateInt;//here you are not accessing it from outside but just comparing value of `MyClass` object property(`myPrivateInt`) to the `Object` you passed
    

    如果它具有相同的属性值,则返回 true 否则 false

    这里是equals的逐步描述

    public boolean equals(Object obj) {
            //you are cheking if the Object you passed is of MyClass type(means it is either MyClass object or any Child of MyClass)
            if (!(obj instanceof MyClass)) return false;
    //if not return false directly, or just cast Object to MyClass(as you know it is MyClass type so it can be casted to MyClass and will not give any cast exception)
            MyClass myClass = (MyClass) obj;
    
            //here you are checking if the object you passed(which is supposed to contain properties MyClass has, so myClass object will also have myPrivateInt variable/property)
    //you are just comparing that value to current MyClass object's myPrivateInt property
    //if that also is equal, you can say both objects are equal
            return this.myPrivateInt == myClass.myPrivateInt;
        }
    

    【讨论】:

      【解决方案3】:

      是的,如果此访问发生在 MyClass 本身的主体内,您可以访问类型为 MyClass 的引用的任何私有成员。

      基于JLS 6.6.1确定可访问性(摘录):

      引用类型的成员是 仅当类型可访问且成员可访问 声明允许访问:

      .......如果成员被声明为私有,则访问 当且仅当它发生在顶层的主体内时才被允许 包含成员声明的类(第 7.6 节)。

      希望有帮助

      【讨论】:

        猜你喜欢
        • 2013-09-29
        • 1970-01-01
        • 1970-01-01
        • 2012-10-03
        • 2012-06-07
        • 2010-12-06
        • 2021-08-25
        • 2017-12-21
        • 1970-01-01
        相关资源
        最近更新 更多