What is the recommended/correct way to access fields in an inner class?
Since
foo
is private, it can be accessed only throughgetFoo()
, right?
In this case, Outer
has access to it too, because Inner
is a member of Outer
.
6.6.1 says:
[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 that encloses the declaration of the member or constructor.
Note that it's specified to be accessible within the body of the top level class that encloses the declaration.
This means, for example:
class Outer {
static class Foo {
private Foo() {}
private int i;
}
static class Bar {{
// Bar has access to Foo's
// private members too
new Foo().i = 2;
}}
}
Whether to use a getter or not is really a matter of taste. The important realization here is that outer classes have access to the private members of their nested classes.
As a recommendation, I would personally say:
- If the nested class is
private
(only the outer class has access to it), I wouldn't bother even giving it a getter unless the getter does a computation. It's arbitrary, and somebody else can come along and choose not to use it. If the styles are mixed, the code has a vagueness. (Doinner.foo
andinner.getFoo()
really do the same thing? We have to go waste time examining theInner
class to find out.) - But you could go through a getter anyway if that's the style you are comfortable with.
- If the nested class isn't
private
, use the getter so the style is uniform.
If you really want to hide the private
members, even from the outer class, you can use a factory with a local or anonymous class:
interface Nested {
Object getFoo();
}
static Nested newNested(Object foo) {
// NestedImpl has method scope,
// so the outer class can't refer to it by name
// e.g. even to cast to it
class NestedImpl implements Nested {
Object foo;
NestedImpl(Object foo) {
this.foo = foo;
}
@Override
public Object getFoo() {
return foo;
}
}
return new NestedImpl(foo);
}
As a pedantic note, your static class Inner {}
is technically a static nested class, not an inner class. class Inner {}
(without static
) would be an inner class.
This is specifically defined to be so:
The
static
keyword may modify the declaration of a member typeC
within the body of a non-inner class or interfaceT
. Its effect is to declare thatC
is not an inner class.
How to access the properties of a nested class with the instance of outer class
Class A and Class B don't have a relationship in this case. Sounds like you might want to make an object of type BClass
a property of AClass
.
public class AClass
{
public BClass BClass { get; set; }
}
public class BClass
{
public string name;
public string id;
}
public class Program
{
public static void Main()
{
AClass newitem = new AClass();
BClass myBClass = newitem.BClass;
}
}
How to access nested class member function from enclosing class where all the members are public in c++?
nested_class1.print();
isn't how you'd call the print
member of an instance of nested_class1
, even if it were declared before there.
The definition of MainClass::func1
must be after the definition of nested_class1
, which must be after the definition of MainClass::nested_class
.
#include <iostream>
class MainClass
{
public:
class nested_class;
void func1();
};
class MainClass::nested_class
{
public:
virtual void print() = 0;
};
class nested_class1: virtual public MainClass::nested_class{
public:
void print();
};
class nested_class2 : virtual public MainClass::nested_class{
public:
void print();
};
void MainClass::func1() {
nested_class1 obj;
obj.print();
}
void nested_class1::print(){
std::cout<<"This is for 1\n";
}
void nested_class1::print(){
std::cout<<"This is for 2";
}
int main(){
MainClass instance;
instance.func1();
}
See it live
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.
What members of the enclosing class can a static nested class access?
In Java nested non - static classes have a hidden reference to the instance of the parent class. That's why they can access all non-static members. The nested class doesn't have such an instance. However, its scope allows it to access the parent members if the parent class passes this.
So what the second quote is saying that the access doesn't happen automatically. You pass the reference to the enclosing class and the nested static class can access it. Otherwise, it doesn't know the address of the enclosing class.
Inner classes inheritance and access to enclosing class methods/fields
Please do not see the terms nested class and inner class as an opposite or something similar. In fact, a nested class simply describes all sorts of classes that are declared inside another class:
- Nested classes that are declared static are simply called static nested classes.
Non-static nested classes are called inner classes. There are three types of them (see JLS §8.1.3 for more info):
- A non-static member class.
- A local class.
- An anonymous class.
The first paragraph you quoted explains that an inner class has access (read: access, not inherit) to the methods and fields of the enclosing instance. Note, it is about an instance, not the class.
The second paragraph tries to explain that there is no relationship between a class and a nested class inside it, except for their locations.
Related Topics
How Much Memory Does a C#/.Net Object Use
Understanding .Asenumerable() in Linq to SQL
Registering a Custom JSONconverter Globally in JSON.Net
Using the "Params" Keyword for Generic Parameters in C#
The Provided Uri Scheme 'Https' Is Invalid; Expected 'Http'. Parameter Name: Via
Why Do Local Variables Require Initialization, But Fields Do Not
Setting Up Hook on Windows Messages
How to Determine If a File Is Binary or Text in C#
Aspect Oriented Programming in C#
How to Draw Directly on the Windows Desktop, C#
Send HTML Email via C# with Smtpclient
Why Does (Int)(Object)10M Throw "Specified Cast Is Not Valid" Exception
Why Can't I Use System.Io.File Methods in an MVC Controller
Does Entity Framework Code First Support Stored Procedures
Asp Net Web API 2.1 Get Client Ip Address