Inner classes can be created within a method or even an arbitrary scope. There are two reasons for doing this:
1. We’re implementing an interface of some kind so we can create and return a reference.
2. We’re solving a complicated problem and we create a class to aid in we solution, but we don’t want it publicly available.
local inner class (an entire class within the scope of a method), for example:
// innerclasses/Parcel5.java
// (c)2017 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
// Nesting a class within a method
public class Parcel5 {
public Destination destination(String s) {
final class PDestination implements Destination {
private String label;
private PDestination(String whereTo) {
label = whereTo;
}
@Override
public String readLabel() {
return label;
}
}
return new PDestination(s); // upcasting
}
public static void main(String[] args) {
Parcel5 p = new Parcel5();
Destination d = p.destination("Tasmania");
}
}
The upcasting in the return statement means nothing comes out of destination() except a reference to a Destination interface. The fact that the name of the class PDestination is placed inside destination() doesn’t mean PDestination is not a valid object once destination() returns. We can use the class identifier PDestination for an inner class inside each class in the same subdirectory without a name clash.
Then, see how we can nest an inner class within any arbitrary scope:
// innerclasses/Parcel6.java
// (c)2017 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
// Nesting a class within a scope
public class Parcel6 {
private void internalTracking(boolean b) {
if (b) {
class TrackingSlip { // inner class, after compiled it is Parcel6$1TrackingSlip.class
private String id;
TrackingSlip(String s) {
id = s;
}
String getSlip() {
return id;
}
}
TrackingSlip ts = new TrackingSlip("slip");
String s = ts.getSlip();
}
// Can't use it here! Out of scope:
// - TrackingSlip ts = new TrackingSlip("x"); // [1]
}
public void track() {
internalTracking(true);
}
public static void main(String[] args) {
Parcel6 p = new Parcel6();
p.track();
}
}
[1]'s compile error:
innerclasses/Parcel6.java:25: error: cannot find symbol
TrackingSlip ts = new TrackingSlip("x");
^
symbol: class TrackingSlip
references:
1. On Java 8 - Bruce Eckel
2. https://github.com/wangbingfeng/OnJava8-Examples/blob/master/innerclasses/Parcel5.java
3. https://github.com/wangbingfeng/OnJava8-Examples/blob/master/innerclasses/Parcel6.java