Skip to main content

Constant pool, identity, and synthetic members

advanced16 min readLesson 126 of 180

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.