JDK-7064370 : Anonymous inner class in incorrectly non-public
  • Type: Bug
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 6u26
  • Priority: P4
  • Status: Closed
  • Resolution: Duplicate
  • OS: linux
  • CPU: x86
  • Submitted: 2011-07-08
  • Updated: 2012-03-20
  • Resolved: 2011-07-11
Related Reports
Duplicate :  
Relates :  
Relates :  
Description
FULL PRODUCT VERSION :
java version "1.6.0_26"
Java(TM) SE Runtime Environment (build 1.6.0_26-b03)
Java HotSpot(TM) Server VM (build 20.1-b02, mixed mode)


ADDITIONAL OS VERSION INFORMATION :
Linux <...> 2.6.18-194.3.1.el5 #1 SMP Thu May 13 13:08:30 EDT 2010 x86_64 x86_64 x86_64 GNU/Linux

A DESCRIPTION OF THE PROBLEM :
Anonymous classes generated by javac are not final according to their modifiers available through Reflection API.

As per JLS (15.9.5 Anonymous Class Declarations), anonymous inner classes are implicitly final.  Indeed, since 1.6 javac appears to set the "final" modifier in the class file generated for an inner class.  However, the modifier seems to be absent in the "InnerClasses" attribute of the enclosing class file, and apparently JVM uses this incorrect value.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Compile the test, run it.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Inner class must have a final modifier, test should complete silently.
ACTUAL -
Test complains that the inner class is not final.

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import java.lang.reflect.Modifier;

public class AnonymousInnerTest {
    public static final Object value = new Object() {
        public String toString() {
            return "*";
        }
    };

    public static void main(String[] args) {
        if (!Modifier.isFinal(value.getClass().getModifiers()))
            System.err.println("anonymous inner class is not final, modifiers: "
                + Integer.toHexString(value.getClass().getModifiers()));
    }
}

---------- END SOURCE ----------

Comments
EVALUATION In past JDK releases, an attempt was made to explicitly mark anonymous classes as ACC_FINAL in the class file (6219964). This was found to have unacceptable behavioral compatability issues, such as changing the serial version UID computation of all anonymous classes, and the change was reverted (6520152). The JLS requires anonymous classes to be implicitly final; this does not necessarily imply that the classes are marked explictly final in their class files. Closing as a duplicate of 6520152.
11-07-2011