Constant pool, identity, and synthetic members
String interning, the Integer boxing cache, and compiler-generated methods you can detect with reflection.
javac compiles to class files (JVM spec ยง4): a constant pool of symbols
plus per-method bytecode for a stack machine. You have no shell in this
sandbox, so javap -c is shown here in prose โ but the consequences of the
constant pool are executable:
String identity โ literals live in the pool, deduplicated:
String a = "adv"; // pool entry
String b = "adv"; // same pool entry
String c = new String("adv"); // fresh heap object
a == b // true โ same constant
a == c // false โ different object
a == c.intern() // true โ intern() returns the pool entry
Boxing cache โ Integer.valueOf caches -128..127 (JLS ยง5.1.7):
Integer.valueOf(127) == Integer.valueOf(127) // true (same cached box)
Integer.valueOf(128) == Integer.valueOf(128) // false (new box each time)
Synthetic constructs โ the compiler generates members you never wrote.
A lambda is desugared to a private synthetic method plus an invokedynamic
call site. Reflection can see the synthetic method:
Runnable r = () -> {};
Arrays.stream(Solution.class.getDeclaredMethods())
.anyMatch(Method::isSynthetic) // true when a lambda exists
Reading bytecode is a skill, but reasoning about identity and generated members is the part you will use weekly.