Domanda

Although, this is a very basic code, it seems there is something fundamentally flawed in Java, or the JVM used by the Eclipse IDE I have used to run the code.

The code runs even though it should not (I think)! The code in A.java simply displays "Hello, I am A!"

Here it is:

import java.lang.*;
import java.util.*;
class A {   
      private void methodA() {System.out.println("Hello, I am A!");}   
      public static void main(String[] args) {   
        A a = new A();   
        a.methodA(); }   
} 

I do not understand why, after creating an instance of class A, main() succeeds in running a private method of class A on that instance. Yes, the main method belongs to class A, but it is not accessing the private method from inside the current object in the context of the "this" reference. In fact, since it is a static method, it cannot access non-static members from within the class. Instead of main(), a non-static member method could have invoked methodA() from inside only. But that is another issue since I have not defined any non-static second method.

Now that the inside-view is talked about, let's come back to the point, the outside-view. As you can see, main() attempts to invoke methodA from outside the object and succeeds! Why isn't private getting treated as private?

I am pulling my hair....

Anyone, please reply...

È stato utile?

Soluzione

Yes, the main method belongs to class A, but it is not accessing the private method from inside the current object in the context of the "this" reference.

That doesn't matter. That's just not the model of accessibility that Java uses. What's important is the class in which the code is written, not whether it's accessing members in the same object.

This is very useful, as otherwise (for example) it would be impossible to implement an equals method using private members of both classes.

This may not be how you would have chosen to specify the language, but it is how Java is specified. See JLS 6.6.1 for details of accessibility. In particular:

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.

Note that protected access is slightly odd here - a protected instance member of class SuperClass can only be accessed within code in SubClass via an expression of either SubClass or a further subclass. But it still doesn't have to be "the same" object.

Altri suggerimenti

private modifer

Methods, Variables and Constructors that are declared private can only be accessed within the declared class itself.

private means "private to the class". Not "private to the instance".

That's what allows implementing things like static factory methods calling private constructors, or equals() or compareTo() methods comparing private fields of objects of the same class, or copy constructors, etc.

Private members of enclosing classes are also accessible from inner classes of this enclosing class, and vice-versa.

After the technically correct answers here's my two cents why I think it is quite reasonable to implement private that way:

As I see it the main reason that private methods and attributes exists is "implementation hiding". You are declaring "Don't use this method from outside my class(!), since it might change or disapear anytime I like". So it makes sense to disallow access from outside the class. But if I'm accessing it from another object of the same class I and make any implementation changes I'm well aware of the changes and the accesses of the private members and can act accordingly.

Another thing to think about:

If class B extends class A, then any B-object also is an A-object, but it can't access the private A-methods. Why would that be if private methods were private to the object?

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top