简体   繁体   English

私人会员访问 Java

[英]Private Member Access Java

Is the private member access at the class level or at the object level.是 class 级别或 object 级别的私有成员访问权限。 If it is at the object level, then the following code should not compile如果是object级别,那么下面的代码应该编译不出来

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

Please clarify if accessing the member i of obj within the messWithI() method of sub is valid请说明在 sub 的 messWithI() 方法中访问 obj 的成员 i 是否有效

As DevSolar has said, it's at the (top level) class level.正如 DevSolar 所说,它处于(顶级)class 级别。

From section 6.6 of the Java Language Specification :来自Java 语言规范的第 6.6 节

Otherwise, if the member or constructor is declared private, then access is permitted if and only if it occurs within the body of the top level class (§7.6) that encloses the declaration of the member or constructor.否则,如果成员或构造函数被声明为私有,则当且仅当它出现在包含成员或构造函数声明的顶级 class(第 7.6 节)的主体内时,才允许访问。

Note that there's no indication that it's restricted to members for a particular object.请注意,没有迹象表明它仅限于特定 object 的成员。

As of Java 7, the compiler no longer allows access to private members of type variables .从 Java 7 开始, 编译器不再允许访问类型变量的私有成员 So if the method had a signature like public <T extends PrivateMember> void messWithI(T t) then it would be a compiler error to access ti .因此,如果该方法具有像public <T extends PrivateMember> void messWithI(T t)这样的签名,那么访问ti将是编译器错误。 That wouldn't change your particular scenario, however.但是,这不会改变您的特定情况。

Note that you don't even need source level access to mess with private fields.请注意,您甚至不需要源级别的访问权限来处理私有字段。 By using java.lang.reflect.AccessibleObject.setAccessibe() , all code can access all private members of all other code unless you specify a security policy that disallows it.通过使用java.lang.reflect.AccessibleObject.setAccessibe() ,所有代码都可以访问所有其他代码的所有私有成员,除非您指定了不允许的安全策略。

private is not by itself a security feature! private本身并不是一个安全功能! It is merely a strong hint to other developers that something is an internal implementation detail that other parts on the code should not depend on.这只是对其他开发人员的强烈暗示,即代码中其他部分不应依赖的内部实现细节。

Neither.两者都不。 Private access is scoped to the enclosing top-level class, so you can access private members of different class in the same top-level class:私有访问的范围是封闭的顶级 class,因此您可以访问同一顶级 class 中不同 class 的私有成员:

class PrivateAccess {
    static class InnerOne {
        private int value;
    }

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

The usual meaning of class access means that you have access to privates of other instances of the same type. class 访问的通常含义意味着您可以访问相同类型的其他实例的私有。 In Java, private access is determined lexically, not by type.在 Java 中,私有访问是按词法确定的,而不是按类型确定的。

Class level. Class 级别。 The idea is that the code of a class (but nothing else) knows how to handle objects of that class.这个想法是 class 的代码(但没有别的)知道如何处理 class 的对象。

If you have access to the class source code anyway, there is little sense in "hiding" anything from you.如果您无论如何都可以访问 class 源代码,那么对您“隐藏”任何东西几乎没有意义。

As others have stated, private, default access ("package private"), protected and perhaps in JDK 7 module are class based (there are very strange rules for nested classes inheritance that I can't remember).正如其他人所说,私有,默认访问(“包私有”),受保护并且可能在 JDK 7 模块中是基于 class 的(嵌套类inheritance有非常奇怪的规则,我不记得了)。 But why?但为什么?

Primarily it's down to methods that act as binary (or more) operators.主要取决于充当二元(或更多)运算符的方法。 For efficient implementation they often require or are easier to write without having to use or modify the public API.为了有效实现,它们通常需要或更容易编写,而无需使用或修改公共 API。 Have a look through at implementations of equals - in good code you'll find direct access of fields with few method calls to this .看一下equals的实现——在好的代码中,你会发现直接访问字段的方法很少调用this (The performance aspect of this is now mostly irrelevant with modern JVMs inlining common calls, but the code quality issue is still there.) (这种性能方面现在与现代 JVM 内联常见调用几乎无关,但代码质量问题仍然存在。)

Just to add to DevSolar's answer, I would expect messWithI to be declared static as such:只是为了添加 DevSolar 的答案,我希望 messWithI 被声明为 static :

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

} I had a hard time even reading what it is that you were trying to do without the 'static' hint... And it also makes it easier to answer your original question -- which is that private members are not limited in scope to just the instance in question. } 我什至很难阅读你在没有“静态”提示的情况下试图做什么......而且它也让你更容易回答你原来的问题——即私人成员在 scope 中不受限制只是有问题的实例。

The same page says, in sub-section 6.6.8, you can also find the following statement:同一页说,在 6.6.8 小节中,您还可以找到以下语句:

A private class member or constructor is accessible only within the body of the top level class that encloses the declaration of the member or constructor.私有 class 成员或构造函数只能在包含成员或构造函数声明的顶级 class 的主体内访问。 It is not inherited by subclasses.它不被子类继承。

The private class member whose access we evaluate here is i .我们在此处评估其访问权限的私有 class 成员是i

public void messWithI() is a method that exists within the body of the top level class where i has been declared, which is, precisely, PrivateMember . public void messWithI()是一种存在于顶级 class 的主体中的方法,其中i已被声明,确切地说是PrivateMember

Your construct meets the statement above, and that is why it runs without problems.您的构造符合上述陈述,这就是它运行没有问题的原因。

Thas is another way to say the same as Jon and Devsolar.这是与 Jon 和 Devsolar 相同的另一种说法。

Access modifiers for class members are related to where the code is written, (in which package, and in which class), regardless of what kind of member the access gets granted: a class member or an instance member. class 成员的访问修饰符与代码的编写位置有关(其中 package,以及在哪个类中),无论授予何种类型的访问权限:ZA2F2ED4F8EBC2CBB4C21A29DC40AB61Z 成员或实例成员。

Logically, you cannot use an instance member of a class if you do not have an instance of the class, but that is a different issue, related to the life-cycle of the member.从逻辑上讲,如果您没有 class 的实例,则不能使用 class 的实例成员,但这是一个不同的问题,与成员的生命周期有关。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM