Inheritance Java private members - java

i have been going through Inheritance in java. My question is if private members are not inherited how come they end up in memory. Is there something going on internally to resolve this issue or they are just hidden/un accesible wihout public member function of the parent class.
here is java doc
"A subclass does not inherit the private members of its parent class. However, if the superclass has public or protected methods for accessing its private fields, these can also be used by the subclass.
A nested class has access to all the private members of its enclosing class—both fields and methods. Therefore, a public or protected nested class inherited by a subclass has indirect access to all of the private members of the superclass."

They are in memory, but you don't have access to them.
Example:
class A
{
private int foo;
public int getFoo( ) { return foo; }
...
}
class B extends A
{
...
}
Every instance of class B does, in fact, contain an integer foo under the hood.
But, you cannot access it directly, because it is declared private. You can access it indirectly, via the getFoo method, because that one is public.

Your object has Class reference in it. Your object's Class had parent Class reference in it. That's why private methods are still in memory - they're referenced by parent class.
They are just inaccessible normally, you can access them with e.g. Method.setAccessible(). You can get Method's by reflection on parent Class.

Related

Inner classes can access even the private members of the outer class.. doesn't it violates the privacy?

My interviewer asked me about inner classes.. After explaining him everything he stopped me on my one sentence- if inner classes can access private members of outer class then doesn't it violate privacy?
I was unable to answer it.
From a JVM perspective, yes, an inner class accessing a private member of the outer class violates privacy.
But, from a Java perspective, no, it does not violate privacy.
JVM perspective
The Java Virtual Machine Specification, section 5.4.4. Access Control says:
A field or method R is accessible to a class or interface D if and only if any of the following is true:
[...]
R is private and is declared in D.
So, the JVM will only allow private members to be accessed from code in the same class, i.e. a nested class cannot access private members of the outer class.
Java perspective
The Java Language Specification, section 6.6.1. Determining Accessibility says:
A member (class, interface, field, or method) of a reference type, or a constructor of a class type, is accessible only if the type is accessible and the member or constructor is declared to permit access:
[...]
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.
So, a private member in a top-level class and/or nested class is accessible from code anywhere within that top-level class. Since nested classes by definition occur within the body of the enclosing top-level class, code in nested classes can access private members of the outer class.
Synthetic access
To solve the discrepancy, the Java compiler creates hidden (synthetic) methods for allowing "private" access between closely related classes, i.e. between a top-level class and all its nested classes.
This is an internal trick of the compiler and is not really documented in the specifications. JVMS, section 4.7.8. The Synthetic Attribute says:
[...] A class member that does not appear in the source code must be marked using a Synthetic attribute, or else it must have its ACC_SYNTHETIC flag set. [...]
The Synthetic attribute was introduced in JDK 1.1 to support nested classes and interfaces.
For more information, do a web search for java synthetic accessor.
See also: Synthetic accessor method warning
Answer is No as inner class is part of the outer class, just like other variable and methods are
All private variable/method of a class can be accessed inside all methods of the same class. An inner class is a special case where an instance of InnerClass can exist only within an instance of OuterClass. Hence it has direct access to the methods and fields of its enclosing instance.
The answer is NO, because inner class has internal link to the outer class and inner class does not exists without concrecte instance of outer class.
But if you add static to the inner class declaration, it means the it does not have link to the outer class and this is the same, when you declare class in it's own file.
That is all, clear and simple.
If you look closely at statement#1 and #2, you will find that the only difference between them is of one extra object (of inner class) that gets created in #1, rest everything access-wise is exactly same.
There is no violation because somewhere you're intentionally leaving the door open through some form of access specifier like public or protected. Inner class doesn't act (or is not capable to act) as a workaround in there, so no violation absolutely.
public class AccessPrivateMemberThruInnerClass {
private int getUniqueId() {
return 101;
}
private class AnInnerClass {
public int getParentID() {
return getUniqueId(); // invokes private method inside a public method.
}
}
public int getUniqueIdForce() {
return getUniqueId(); // invokes private method inside a public method.
}
public AnInnerClass getInnerClassObject(){
return new AnInnerClass();
}
public static void main(String[] args) {
AccessPrivateMemberThruInnerClass obj = new AccessPrivateMemberThruInnerClass();
System.out.println(obj.getInnerClassObject().getParentID()); // #1
System.out.println(obj.getUniqueIdForce()); // #2
}
}
Answer : No inner class does not voilate the privacy of outer class.
Explanation : All instance methods defined in a class are able to access the private or not private fields and methods defined in the class. This happens as all the instance methods and fields belong to the current object of the class.
Same is true for any inner (non static) class, it has an implicit reference of outerclass current object.
This is the reason as why you can only create the object of inner (non static) class with the help of an object of outer class. If you create the object of inner class inside any instance method of outer class then it is created with the help of implicit current object reference of the outer class.
If you have inner class which is static, then it does not has implicit reference to current object of outer class. Any instance field or method belong to an Object of the class. Hence static inner class can not access any private or non private instance field or method of outer class.
You can set reference of outer container class object explicitly and then it can acess. Now with the help of this explicitly set reference of outer class you can access the private Fields and methods.
So now lets modify the question as why inner static class with an explicit reference of outer class can acess and modify private methods and fields ?
Answer is related to our decision for having such design. The intention of defining any entity within the scope of a class is belongingness. If belongingness is missing then you should reconsider your decision lf making the class as inner (static or non static). Inner classes should be made when we wish to encapsulate a sub responsibility to an entity. This makes the related responsibility still cohesive.
Iterator is a part of any Collection and hence it is inner class. Custom AsyncTask class defined in custom Activity class in android is often made as private static (with weak reference of outer class activity) to prevwnt activity leak as the intention is to modify the fields which are private.
P.S : Afer compiler compiles the code it generates separate files for inner class and you can refer the link to understand as how the interaction of fields of one class being accessible to other class happens when other class is defined as inner class
https://stackoverflow.com/a/24312109/504133 . Actually synthetic getters and setters are injected in the code by compiler so as nested static class can access private fields using these. But still this is backend task done by langauge tools.

Are private fields and methods inherited? [duplicate]

This question already has answers here:
Do subclasses inherit private fields?
(21 answers)
Closed 4 years ago.
I did a little bit of research to know if private instance fields and methods are inherited by a subclass from its superclass.
Actually, I red on different forums contradictory answers but the most convincing one was that, like the java documentation tells, private fields and methods are never inherited BUT that instances of the subclass allocate some memory for the private fields and methods of the superclass.
However, on my most reliable source of documentation, which is the book "java in a nutshell 6th edition" it is said :
This existence of potentially inaccessible members seems to be in conflict with the statement that the members of a class are always accessible within the body of the class. To clear up this confusion, we define “inherited members” to mean those superclass members that are accessible.
Then the correct statement about member accessibility is: “All inherited members
and all members defined in this class are accessible.” An alternative way of saying
this is:
• A class inherits all instance fields and instance methods (but not constructors)
of its superclass.
• The body of a class can always access all the fields and methods it declares
itself. It can also access the accessible fields and members it inherits from its
superclass.
So according to my understanding I came to the conclusion that a subclass inherits ALL fields and methods (including the private ones) from its superclass, but somehow the body of the subclass cannot access the private (and eventually other invisible) members of the superclass.
If I understood well what the book says, isn't that contradictory with what the java documentation tells - that private members are not even inherited -?
Or did I just missed something while reading the book?
Whether a member is inherited or not is primarily relevant to lookup procedures. If e.g. a class B extends A, when the language specification says that private members are not inherited, what this means is that the private members of A only belong to instances of B while viewing them as an A.
The classic example of this looks something like this:
class B extends A {}
class A {
private void m() {}
public static void main(String[] args) {
B b = new B();
b.m(); // error: "cannot find symbol"
A a = b;
a.m(); // fine: m() is a member of A
}
}
There is indeed a method m() which we can call on the instance of B, but the method lookup procedure fails to find it unless we're viewing the B as an A.
With private fields, the in-memory representation of an object will include the private fields of its superclasses, even though we say they are not inherited in JLS terms.
Some further clarifications here are in §8.2:
Members of a class that are declared private are not inherited by subclasses of that class.
Only members of a class that are declared protected or public are inherited by subclasses declared in a package other than the one in which the class is declared.
As well as in §8.3:
A class inherits from its direct superclass and direct superinterfaces all the non-private fields of the superclass and superinterfaces that are both accessible to code in the class and not hidden by a declaration in the class.
A private field of a superclass might be accessible to a subclass - for example, if both classes are members of the same class. Nevertheless, a private field is never inherited by a subclass.
(§8.4.8 also has similar rules for methods.)
These clarify that inheritance does have something to do with accessibility, but there's not a strict 1:1 correspondence. For example, in the following, the field x is accessible to, but not inherited by class B (per §8.3 above):
class Outer {
static class A {
private int x;
}
static class B extends A {
B() {
super.x = 1; // accessible, but must be qualified
}
}
}
One way to put this is that accessibility is a necessary, but not sufficient, condition for inheritance. (In other words, inheritance requires accessibility, but not vice versa.)
Colloquially, it's probably correct to say that private members are inherited, in the sense that 1) a subclass object stores the private variables of its superclasses and 2) the private methods of the superclasses can be invoked on a subclass instance. This is, however, not how the JLS is using the word.
Consider
class A {
private int x;
public A() {
x = 10;
}
public int foo() {
return x * 2;
}
}
public class B extends A {
public B() {
super(); // Calls A's constructor assigning x.
// anything
}
}
int n = B().foo(); // n == 20
It is apparent that an instance of B does carry the member x, with its value. If B did not do so, it could not run the inherited method foo, because that method's implementation in A needs the value of x.
Indeed, B cannot directly access x. But as long as it has any methods that (transitively) depend on that value, via inheritance from A, it must allocate storage for x.
In other words, B is A with something added. Nothing can be removed by inheritance. It can only be made invisible, it it was private. But it's still there, not gone.

Java accessing private superclass member through protected getter

I know that in Java you can access a private member of a superclass in the subclass as long as the superclass provides a public or protected getter method. I also know however that the subclass does not actually inherit the private member. Considering the following scenario....
Class A {
private var = 2;
protected int getVar(){
return var;
}
}
Class B extends A{
public void printVar(){
System.out.println(getVar());
}
}
Class Main{
public static void main(args []){
B b= new B();
b.printVar();
}
}
I want to understand, since we are creating an instance of the subclass B, what exactly and when is that private member allocated to memory, and what is it's scope? How does it even exist since an instance of A was actually never created? It's not a static variable, or final so is it stack dynamic or implicitly heap dynamic? I thought that when you instantiate a subclass from a super class you inherit the members that aren't private and methods as well and then those get instantiated as part of an object instance of the sub class (unless they're overridden etc), so there is only one object allocated as a heap dynamic variable. But if these private members are not inherited then does the compiler simply provide a stack dynamic reference to them in case the inherited getter method is invoked and only in that case?
Your assumption that the private members of the super-class are not inherited by the sub-class is wrong. All members are inherited. The private members of the sub-class are part of the sub-class instance, but they can't be accessed directly by the code of the sub-class.
Having a protected getter in the super-class that returns the value of the private member gives the sub-class a means to access the value of the private member (though it can't modify it, unless you also have a protected or public setter in the super-class).
I also know however that the subclass does not actually inherit the private member.
Yes it does. An instance of B is an instance of A, and it contains all the same fields. You don't have direct access to the private fields anymore, but they still exist.
How does it even exist since an instance of A was actually never created?
When you create B, a constructor in A is called as well, which makes sure that the B instance is correctly initialized as a valid A. Don't think of a subclass as something different than it's superclass. A B is still an A; it just does more.

Public constructor of a private class [duplicate]

This question already has answers here:
Should we declare a public constructor when the class is declared as package private?
(2 answers)
Closed 8 years ago.
I am new to Java. I want to know what it is the use of public constructor in a private class. Private class inside the class can be initialized from the same class then what it is the use to make the constructor of private class to public?
public class MainActivity extends Activity {
private class AcceptThread extends Thread {
public AcceptThread() {
}
}
}
There doesn't seems to be any real use case for public or protected modifiers with private classes. If you have multiple classes in a single file though (but not nested or local), you need non-private constructors to instantiate the private classes.
// X.java
public class X {
private Y y = new Y();
}
class Y {
Y () {
// if this were private, X wouldn't be able to create an instance of Y
}
}
Actually default or protected visibility would be enough to create an instance in this case. All non-private modifiers allow you to create instances from other classes within the same package but practically have the same visibility.
The private class isn't visible to classes outside of the package, so public methods have no use here.
The private class can't be extended by classes outside of the package, so protected has no use either.
Even when using reflections, a public constructor is not accessible by default from other packages and will throw a IllegalAccessException. It checks the class visibility first, then the member visibility.
The default modifier is the most restrictive modifier that allows you to directly call the constructor from other classes, so package-private seems to be the most appropriate visibility for the constructor and also any other non-private methods. This also has the advantage that if you change the class visibility in the future, you don't accidentally expose the constructor or any methods to the public.
You know, I ask myself this question almost each time I make a private inner class, but I always assumed that there could be some (possibly contrived) reason for a public constructor. So #kapep 's answer got me tingling and encouraged to find ways to require a public constructor on a private inner class, but the more I think and experiment with it, the more I think the holes are plugged.
Possible angles, all of which failed me:
Serialisation: When unmarshalling an object whose superclass is not serializable, the superclass needs a no-arg constructor accessible from the subclass. So, protected should always suffice here.
Reflective tools: Code that uses reflection to get the inner class constructor through a returned instance. Fails because the type visibility is checked first, as #kapep pointed out, though it leaves a rather interesting error message:
Exception in thread "main" java.lang.IllegalAccessException: Class A can not access a member of class contrived.B$C with modifiers "public"
Inner class extension shenanigans: Don't try this at home:
package a;
class Outer {
private class Inner {
}
}
package b;
// compile error: Outer.Inner has private access in Outer
class Extender extends a.Outer.Inner {
Extender(a.Outer outer) {
outer.super();
}
}
Seemed promising at first, but I didn't get too far with that one.
In the end, I could not find a way to make a public constructor on a private inner class useful.
Then why is this technically legal despite having no use? Probably because the compiler automagically inserts a no-arg public constructor when no other constructor is provided. Hence the language should not disallow this constructs. More of an artefact than a reason, though.

Which members are not inherited in a child class?

I'm trying to answer the following question:
A child class would not inherit certain members of the parent class. Name three
such members.
I know private members are not inherited to child classes and default members are not inherited outside of the package. Can anyone complete the answer?
Edited:-
I believe that static members are inherited according to below demonstration
public class sup {
public static void main(String agr[]){
}
protected static int staticInt=0;
protected final int finalInt=3;
protected int protectedInt=0;
public String publicString = "";
private int privateInt=8;
}
class sub extends sup{
public void del(){
staticInt=1;
staticInt=finalInt;
}
}
from JLS for Class Member
Constructors, static initializers, and instance initializers are not members and therefore are not inherited.
from Oracle Java Documentation for Inheritance :
A subclass inherits all the members (fields, methods, and nested
classes) from its superclass. Constructors are not members, so they
are not inherited by subclasses, but the constructor of the superclass
can be invoked from the subclass
So I think you're missing constructors here .
Static Methods and fields are not inherited too, when they are rewritten in subclasses, they just reuse the signature and hide the implementation of the method/field in the parent class.
For Inheritance of static fields and methods, refer to this discussion as steted by Duncan, and this great tutorial Overriding vs Hiding
None-Answer to make a case for terms usage.
Members which are visible in the child class is answered above. Members being both fields and methods (each having its own namespace).
Inheritance as being part of the child instance, is another question: also invisible private members are "inherited" as such. Static members are part of the class instance and are not inherited (cannot be overriden too). All final methods cannot be overriden.
Arguable constructors are not inherited; you have to define the same signature again in a new child constructor.
Other declarations in a class could be class definitions. There the keyword static has a different meaning, and one may make obvious statements on visibility/inheritance. For instance with respect to non-static inner classes, which have an <outer-class>.this (recursive notion).
Constructors and static initializers and instance initializers.
you can't inherit a private field,and constructor.
you can't inherit a constructor because they are not member of super class. you can invoke a super class constructor form it's sub class. and you can also access a private member of super class can be accessed through public or protected method of super classes.

Categories

Resources