Nested class' access to enclosing class' private data members
Member x
and y
are non-static data member of Enclosing
, which means that they only exist within a concrete object of Enclosing
class. Without a concrete object, neither x
nor y
exist. Meanwhile, you are trying to refer to x
and y
without an object. That can't be done, which is what the compiler is trying to tell you.
If you want to initialize members Inner::foo
and Inner::bar
from x
and y
, you have to pass a concrete object of Enclosing
type into the Inner
s constructor. For example
class Enclosing::Inner {
explicit Inner(const Enclosing& e) : foo(e.x), bar(e.y)
{}
//...
};
Extra note: in the original C++98 the inner class has no special privileges is accessing the outer class. With C++98 compiler you'd either have to give the inner class the necessary privileges (friendship) or expose the members x
and y
as public. However, this situation was classified as a defect in C++98, and it was decided that inner classes should have full access to outer class members (even private ones). So, whether you have to do anything extra with regard to access privileges depends on your compiler.
How do inner class access enclosing class' private members in higher versions of Java?
The only thing that stops a class from accessing another class’s private
members, is the JVM (or precisely its verifier) rejecting the access. So all it needs to make it possible, is the collaboration of the JVM to allow it.
While Java 1.1 introduced inner classes in a way that did not require changes to the JVM, the JVM has gone through so many changes in the meanwhile, that it is rather surprising that it took until Java 11 to change that.
Java 11 introduced the NestHost
and NestMembers
bytecode attributes to allow class files to denote that they belong to a so called “nest”. All classes belonging to the same nest are allowed to access each others private
members. As said, the only thing that needed to be changed, is the JVM’s verifier to allow such access. And, of course, the compiler to utilize this feature. See also JEP 181.
So you could say that the JVM still doesn’t know anything about inner classes, because which classes belong to a nest, is decided by whichever tool generated the class files (e.g. the Java source code compiler). So it is possible to produce class files with other tools using nests without following the inner class semantic.
For completion, it should be mentioned that class files do also contain the information about inner class relationships, using the InnerClasses
attribute. But this is only used by compilers and Reflection, whereas the JVM doesn’t use this information when deciding whether an access is legal or not.
Can enclosing class access nested class?
Can enclosing class access nested class?
Yes, if the enclosing class have an instance (an object) of the nested class.
A class is a class is a class... Nesting doesn't matter, you must always have an instance of the class to be able to call a (non-static) member function.
Subclass of a public nested class is unable to access private members of enclosing class
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();
}
}
Nested class member access on C++11
To close this question I'll take this as an answer:
"No, it's not treated as a member of the class, it's just scoped inside of it like anything else. You'll need an instance of Enclosing to access it's members."
- this and several other comments addresses the problem in my code. Basically this is something that remains true for C++11.
In Java nested classes, can the enclosing class access private members of inner classes?
Yes, that's fine. From the JLS, section 6.6.1:
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.
You can even refer to a private member of nested type X within another nested type Y so long as they share a top-level class.
At the bytecode level, I believe this is all implemented by adding synthetic package-access methods.
Related Topics
C++ Delete Does Not Free All Memory (Windows)
Why There Are Three Unexpected Worker Threads When a Win32 Console Application Starts Up
Factory Method Implementation - C++
What Does Exactly the Warning Mean About Hidden Symbol Being Referenced by Dso
Equivalent of Console.Readline() in C++
Why Can't I Initialize a Variable-Sized Array
Throwing C++ Exceptions Across Dll Boundaries
How to Open a Folder in %Appdata% with C++
Understanding Virtual Base Classes and Constructor Calls
Speed Accessing a Std::Vector by Iterator VS by Operator[]/Index
How to Control My Pc's Fan Speed Using C++ in Vista
Memoized, Recursive Factorial Function
Can You Really Have a Function/Method Without a Body But Just a Try/Catch Block