Did you ever wonder about the paradox (or not paradox) of independent or dependent living of so called inner classes (sometimes used in pattern like observer, strategy …) in Java? Today I came to a point where I needed some further clarification. The inner class will compile to Outer$Inner.class. But it will not be instantiable as such outside the Outer class. You still can access a private member of Outer by Methods of Inner, but that is not much different from using such Methods in Outer. Trying to reach the Outer private members by deriving the Inner class from a global (outern) super class (PreInner) and casting the Inner object to PreInner type to make it “available” in global scope will only result in reaching the superclasses member. Of course all this is reasonable regarding the Java specification, but it is different when it comes to “feel” that.

Here some code samples:

public class Outer {

  String name;
  private String intimate;
  private String intimate2 = "intimate2 in Outer";

  public Outer(String s) {
    name = s;
  }

  public String getName() {
    return name;
  }

  public String getIntimate() {
    return intimate;
  }
  public Inner getWrappedName() {
    return new Inner(name);
  }

  // the inner class
  class Inner extends PreInner{
    //public String innername = "innen";

          public Inner(String s) {
    innername = s;
    }

     public String getName() {
    return innername;
     }

     public void setIntimateInOuter(String s){
    intimate = s;
     }

     public void setIntimate2WillYouReachThatOfOuter(String s) {
    intimate2 = s;
     }
  }
}
-------------------------
public class PreInner {
  public String innername = "innen";
  public String intimate2 = "intimate2 in PreInner";
}
-------------------------

public class RunOuter {

  public static void main(String[] args) {

    Outer out = new Outer("name");
    // cannot be resolved! :
    //Inner in = out.getWrappedName();
    //with idea:
    // in.setIntimateInOuter("intimate through inner");

    //that works:
   out.getWrappedName().setIntimate2WillYouReachThatOfOuter(
                                     "intimate2 over Inner");
    PreInner in = out.getWrappedName();

    System.out.println(in.innername);
    System.out.println("intimate2 from Inner " + in.intimate2);
    

          //that works too:
    out.getWrappedName().setIntimateInOuter("intimate over Inner");
    System.out.println(out.getWrappedName().getName() + 
                           " == " + out.getName());
    System.out.println("Outer Intimate: " + out.getIntimate());

  }
}

gives output:

name
intimate2 from Inner intimate2 in PreInner
name == name
Outer Intimate: intimate over Inner