0 Replies Latest reply: Feb 28, 2013 10:26 AM by 994002 RSS

    Inner class inconsistency between signature and descriptor.

    994002
      Hi all!

      I'm trying to understand if there's a reason in the spec for the discrepany between java descriptors and signatures for inner classes. (I'm looking directly at the content of the class files here, but I use javap to illustrate).

      ( n.b. I have tried this on JDK 1.6.0_33 and 1.7.0_05, both have the same issue when viewed with javap from Java 7 - java 6's javap doesn't seem to show any generic signature info )


      Consider:


      public class InnerClassTest1 {

      public int getX() {
      return new Inner1(new ArrayList<String>()).getX(4);
      }

      public class Inner1 {
      private final List arg;

      public Inner1(List arg) {
      this.arg = arg;
      }....


      and the same, with generics on the inner class


      public class InnerClassTest2 {

      public int getX() {
      return new Inner1(new ArrayList<String>()).getX(4);
      }

      public class Inner1<E> {
      private final List<E> arg;

      public Inner1(List<E> arg) {
      this.arg = arg;
      }.....



      If you look at the output of javap -cs [ USING JAVA 7 RUNTIME ] on the inner classes, they're surprisingly different!

      public org.benf.cfr.tests.InnerClassTest1$Inner1(org.benf.cfr.tests.InnerClassTest1, java.util.List);
      Signature: (Lorg/benf/cfr/tests/InnerClassTest1;Ljava/util/List;)V

      vs

      public org.benf.cfr.tests.InnerClassTest2$Inner1(java.util.List<E>); <--- Generic signature missing the implicit outer class
      Signature: (Lorg/benf/cfr/tests/InnerClassTest2;Ljava/util/List;)V <--- non generic descriptor based signature is correct.



      Using java 6, they both look the same, but javap doesn't show generics info.

      Looking at the classfile / constpool / signature attributes, I can see that in the latter case

      the DESCRIPTOR for <init>Inner1 is (Lorg/benf/cfr/tests/InnerClassTest2;Ljava/util/List;)V

      but the SIGNATURE (i.e the signature attribute on the method) for the same is *(Ljava/util/list<TE;>)V* , which is wrong.



      I think that when javac builds the signatures for inner classes, it is skipping the implicit argument for the outer class's this pointer.


      http://www.benf.org/files/innerClassTest.tgz contains sample files, and output when viewed in JAVAP under java 7.



      Does anyone know what's going on here?