Access via the Reflection API

Without nest-based access control, reflection capabilities are also limited. For example, before JDK 11, the following snippet of code would throw IllegalAccessException:

Car newCar = new Car();
Engine engine = newCar.new Engine();

Field powerField = Engine.class.getDeclaredField("power");
powerField.set(engine, power);

We can allow access by explicitly calling powerField.setAccessible(true):

...
Field powerField = Engine.class.getDeclaredField("power");
powerField.setAccessible(true);
powerField.set(engine, power);
...

Starting with JDK 11, there is no need to call setAccessible().

Moreover, JDK 11 comes with three methods that enrich the Java Reflection API with support for nests. These methods are Class.getNestHost(), Class.getNestMembers(), and Class.isNestmateOf().

Let's consider the following Melon class with several nested classes (Slice, Peeler, and Juicer):

public class Melon {
...
public class Slice {
public class Peeler {}
}

public class Juicer {}
...
}

Now, let's define a Class for each of them:

Class<Melon> clazzMelon = Melon.class;
Class<Melon.Slice> clazzSlice = Melon.Slice.class;
Class<Melon.Juicer> clazzJuicer = Melon.Juicer.class;
Class<Melon.Slice.Peeler> clazzPeeler = Melon.Slice.Peeler.class;

In order to see NestHost of each class, we need to call Class.getNestHost():

// class modern.challenge.Melon
Class<?> nestClazzOfMelon = clazzMelon.getNestHost();

// class modern.challenge.Melon
Class<?> nestClazzOfSlice = clazzSlice.getNestHost();

// class modern.challenge.Melon
Class<?> nestClazzOfPeeler = clazzPeeler.getNestHost();

// class modern.challenge.Melon
Class<?> nestClazzOfJuicer = clazzJuicer.getNestHost();

Two things should be highlighted here. First, note that NestHost of Melon is Melon itself. Second, note that NestHost of Peeler is Melon, not Slice. Since Peeler is an inner class of Slice, we may think that its NestHost is Slice, but this assumption is not true.

Now, let's list NestMembers of each class:

Class<?>[] nestMembersOfMelon = clazzMelon.getNestMembers();
Class<?>[] nestMembersOfSlice = clazzSlice.getNestMembers();
Class<?>[] nestMembersOfJuicer = clazzJuicer.getNestMembers();
Class<?>[] nestMembersOfPeeler = clazzPeeler.getNestMembers();

All of them will return same NestMembers:

[class modern.challenge.Melon, class modern.challenge.Melon$Juicer, class modern.challenge.Melon$Slice, class modern.challenge.Melon$Slice$Peeler]

Finally, let's check nestmates:

boolean melonIsNestmateOfSlice 
= clazzMelon.isNestmateOf(clazzSlice); // true

boolean melonIsNestmateOfJuicer
= clazzMelon.isNestmateOf(clazzJuicer); // true

boolean melonIsNestmateOfPeeler
= clazzMelon.isNestmateOf(clazzPeeler); // true

boolean sliceIsNestmateOfJuicer
= clazzSlice.isNestmateOf(clazzJuicer); // true

boolean sliceIsNestmateOfPeeler
= clazzSlice.isNestmateOf(clazzPeeler); // true

boolean juicerIsNestmateOfPeeler
= clazzJuicer.isNestmateOf(clazzPeeler); // true
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset