but it's really just a compiler trick, as all classes will end up having their own .class file, not matter whether they are Outer or Inner (compiler does some name mangling to arrive at unique names). In addition to Inner and Outer classes, there's also anonymous classes and file level classes.

Don't know if it helps but here's some toy code:
\n// Outer Class declaration\npublic class Outer {\n\n   // Outer Class properties/methods\n   int propOuter;\n   int methOuter(int k) {\n      System.out.println("Hello Outer Class method");\n      propOuter = k;\n      return propOuter;\n   }\n\n   // Inner Class declaration\n   class Inner {\n      // Inner Class properties/methods\n      int propInner;\n      int methInner(int k) {\n         System.out.println("Hello Inner Class method");\n         propInner = k;\n         methOuter(k);     // visibility of Outer Class properties/methods\n         return propInner;\n      }\n   }\n\n   // Outer Class constructor\n   Outer(int k) {\n      propOuter = k;\n\n      // instantiate an Inner Class from within the Outer Class instance\n      Inner inner = new Inner();\n      methOuter(5);\n      inner.methInner(6);\n\n      // do an anonymous class for grins\n      Object anon = new Object() {\n         int propAnon;\n         public String toString() {\n            System.out.println("Hello Anonymous Class method");\n            propAnon = 2;\n            propOuter = 3; // visibility of Outer Class properties/methods\n            methOuter(4);\n            return "reflection would be better";\n         }\n      };\n      // call method on the anonymous class\n      anon.toString();\n   }\n\n   // main static entry point - do some instantiating\n   public static void main(String[] args) {\n      // instantiate the Outer Class\n      Outer outer = new Outer(0);\n\n      // instantiate the FileLevel Class\n      FileLevel filelevel = new FileLevel();\n      filelevel.methFileLevel(1);\n   }\n}\n\n// FileLevel Class declaration\nclass FileLevel {\n   // FileLevel Class properties/methods\n   int propFileLevel;\n   int methFileLevel(int k) {\n      System.out.println("Hello FileLevel Class method");\n      propFileLevel = k;\n      return propFileLevel;\n   }\n}\n