Reputation: 65
I have read a sentence here like below
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 super class.
Now I have a code like below
class Locker {
private String secret = "This is my secret";
public class Util { }
}
class StealSecret extends Locker.Util { }
But I am getting an compile time error like below
No enclosing instance of type Locker is available due to some intermediate constructor invocation
I am unable to understand what exactly is causing the compile time error. Is it that what I read in the link is wrong ?
Please give me an example explaining the way to access the private members of enclosing class by extending the inner class
Upvotes: 0
Views: 1014
Reputation: 279910
The other answers have explained the reason for the exception, but have not addressed
Please give me an example explaining the way to access the private members of enclosing class by extending the inner class
The quote from your document states
A nested class has access to all the private members of its enclosing class—both fields and methods.
A nested class is a class that is declared within another. Locker.Util
is a nested class. StealSecret
is not (even if it did compile, see below for a trick to do that).
If you really need to extend that inner class and have access to the private
members of the Locker
class, you'll need to declare the subclass within Locker
as well
For example,
public class Locker {
private String secret = "This is my secret";
public class Util {
}
public class StealSecret extends Locker.Util {
public StealSecret() {
System.out.println(secret); // access
}
}
}
The StealSecret
class extends an inner class, which requires a reference to an instance of that inner class' enclosing class. You can use this trick to provide that reference
class StealSecret extends Locker.Util {
public StealSecret(Locker enclosing) {
enclosing.super();
}
}
Upvotes: 3
Reputation: 19194
Let's start with the quotation you are analyzing:
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 super class.
In the sentence above, the enclosing class is your Locker
, the nested class is Locker.Util
and the private field is secret
. For a subclass to inherit the nested class, it means that you need to extend the enclosing class, not the nested class:
class StealSecret extends Locker {
public StealSecret() {
StealSecret.Util u = new StealSecret.Util();
System.out.println(u.getSecret());
}
}
in this case, the inherited nested class instance would have indirect access to the private enclosing class field secret:
class Util {
String getSecret() { return secret; }
}
In here you can see how the inherited nested class will access the private field for the enclosing class: https://ideone.com/NK9Brs
The compile error you get:
No enclosing instance of type Locker is available due to some intermediate constructor invocation
is a by-product of your mistake of having StealSecret
try to extend Locker.Util
outside of the Locker
classand that is because a non-static nested class cannot exists without an instance of its enclosing class.
Upvotes: 1