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?
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.
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.
No, we cannot declare a top-level class as private or protected. It can be either public or default (no modifier).
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.
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.
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."
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.
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(); }
}
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
).
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(); }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With