We will discuss how member inner classes are compiled.
Reference: https://www.amazon.com/Java-Language-Features-Modules-Expressions/dp/1484233476
A member inner class is defined inside a class the same way a member field or a member method. It could be private, package-level, protected, public.
Naming convention: <outer-class-name>$<member-inner-class-name>
- Inner classes are hidden by default in Intellij explorer.
- Configuration of javap decompiler is child's play:
- ctrl + alt + s (Settings)
- external tools
+(plus)- Program:
$JDKPath$\bin\javap.exe - Arguments:
-c $FileClass$-cPrints out disassembled code
- Working directory:
$OutputPath$
- Program:
- Using javap from context menu:
- right click on the class -> External Tools -> javap
- Using javap from terminal: "java_home\bin\javap.exe" -c path_to_compiled\Outer$Inner.class
- The easiest example, package:
easyis compiled to two classes:class Outer { class Inner { } }Outer$Inner.classclass Outer$Inner { final Outer this$0; Outer$Inner(Outer outer) { this$0 = outer; super(); } }- final field for
Outerinstance was added - note that
super()is after setting the field - a one-param constructor that accepts
Outeris inserted during compilation
- final field for
Outer.classclass Outer { Outer() { } }- the coupling between
OuterandInneris removed in the compilation
- the coupling between
- Inner class has constructor, package:
constructoris compiled to two classes:class Outer { class Inner { Inner(String s) { } } }Outer$Innerclass Outer$Inner { final Outer this$0; Outer$Inner(Outer outer, String s) { this$0 = outer; super(); } }- additional param (
Outer) was added to the existing constructor
- additional param (
Outer.classsame as(1.)
- accessing private fields, package:
accessing.privis compiled to two classes:class Outer { private String s = "outer"; class Inner { String getS() { return s; } } }Outer.classclass Outer { private String s = null; Outer() { s = "outer"; } static String access$000(Outer outer) { return outer.s; } }- static method for extracting private field (flagged by compiler - we don't have direct access)
Outer$Innerclass Outer$Inner { final Outer this$0; Outer$Inner(Outer outer) { this$0 = outer; super(); } String getS() { return Outer.access$000(this$0); } }
- accessing non-private fields, package:
accessing.nprivis compiled to two classes:class Outer { String s = "outer"; class Inner { String getS() { return s; } } }Outer$Innerclass Outer$Inner { final Outer this$0; Outer$Inner(Outer outer) { this$0 = outer; super(); } String getS() { return this$0.s; } }Outer.classclass Outer { private String s = null; Outer() { s = "outer"; } }- no static method this time