What's the Best Way of Accessing Field in the Enclosing Class from the Nested Class

What is the recommended/correct way to access fields in an inner class?

Since foo is private, it can be accessed only through getFoo(), 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. (Do inner.foo and inner.getFoo() really do the same thing? We have to go waste time examining the Inner 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 type C within the body of a non-inner class or interface T. Its effect is to declare that C 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:

  1. Nested classes that are declared static are simply called static nested classes.
  2. Non-static nested classes are called inner classes. There are three types of them (see JLS §8.1.3 for more info):

    1. A non-static member class.
    2. A local class.
    3. 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



Leave a reply



Submit