Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why doesn't Java allow me to access private method through method of the same class?

I have code that looks like this:

public class A<T extends A> {
    private T one() { return (T) this;}

    protected T two() { return (T) this;}

    protected void three() { two().one(); }
}

And IntelliJ tells me that "one() has private access in A", but hey, why can't I call the private member of the same class?

like image 202
saroff Avatar asked May 02 '15 21:05

saroff


People also ask

Can I access a private function of a class in the same class?

You can access private members from any code block that is defined in the same class. It doesn't matter what the instance is, or even if there is any instance (the code block is in a static context). But you cannot access them from code that is defined in a different class.

Can a private method be called by any other method in the same class?

We can call the private method of a class from another class in Java (which are defined using the private access modifier in Java). We can do this by changing the runtime behavior of the class by using some predefined methods of Java. For accessing private method of different class we will use Reflection API.

Can we use private with class in Java?

No, we cannot declare a top-level class as private or protected. It can be either public or default (no modifier).

What is a private private method in Java?

Private methods in Java have a private access modifier which means they have limited access to the defining class and are not accessible in the child class in inheritance; that is why they are not eligible for overriding. However, a method can be created in the child class and could be accessed in the parent class.

Can a method be created in the child class in Java?

However, a method can be created in the child class and could be accessed in the parent class. This tutorial demonstrates how to create and use private methods in Java. As mentioned above, private methods are only accessible in the defining class; we consider the points below for the private methods.

Why are members of a class private in Java?

Because that's how Java works? "Otherwise, the member or constructor is declared private, and 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."

How to access the private constructor of a class in Java?

To access the private constructor, we use the method getDeclaredConstructor (). The getDeclaredConstructor () is used to access a parameterless as well as a parametrized constructor of a class. The following example shows the same.


3 Answers

private members can be accessed only within class in which they ware declared. So if you have class

class X{
    private int field = 1;
    private void method(){}
    void foo(X x){
        x.field = 2;
        x.method(); // this is OK, because we are accessing members from instance of X 
                    // via reference of class X (which is same class as this one)
    }

    void bar(Y y){// = lets assume that Y extends X
        y.field = 3;
        y.method(); // ERROR: we can't access `method()` 
    }
}

As you see we are not allowed to access private member from derived class even if we are inside class in which this member was declared.

Possible reason for this is that private members are not inherited to interface of derived class (which is kind of whole purpose of private visibility modifier). Because of that in such classes it is possible to redeclare these members any way author wants, for instance someone could create class like this one:

class Y extends X{
    private String field = "foo";
    private String method(){
        return "bar";
    }
}

So as you see it is possible that by calling y.method() you are trying to access method declared in Y class, but you don't have access to it from X class (due to encapsulation). And this is scenario compiler assumes because fields and private methods are not polymorphic.

To avoid this confusion you will need to explicitly state that you want to invoke private member from current class X by using casting

void bar(Y y){
    ((X)y).method(); 
}

Same thing happens for <T extends A>. Since T can be any subclass of A compiler will not allow access to its private members. So you will need to cast it back to A

class A<T extends A> {
    private T one() { return (T) this;}

    protected T two() { return (T) this;}

    protected void three() { ((A)two()).one(); }
}
like image 188
Pshemo Avatar answered Oct 21 '22 01:10

Pshemo


This compiler error was introduced in Java 7 as per http://www.oracle.com/technetwork/java/javase/compatibility-417013.html:

Description: In JDK 5.0 and JDK 6, javac erroneously allowed access to private members of type-variables. This is wrong, as the JLS, Java SE 7 Edition, section 4.4, states that the members of a type-variable are the members of an intersection types whose components are the type-variable bounds (intersection types are defined in section 4.9) - and intersection types do not inherit private members from their components

The type of T may not be A. It can be of type B that is a subclass of A. In this case, accessing the private method one() does not conform to the inheritance rule which says that a subclass (that is class B) does not inherit the private members of its parent class (that is class A).

like image 34
M A Avatar answered Oct 21 '22 02:10

M A


why i can't call the private member of the same class?

Because you try to call the private method from T wich can be derived from A. If you add a cast to A again it will work:

protected void three() { ((A)two()).one(); }
like image 5
tomse Avatar answered Oct 21 '22 00:10

tomse