Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-6657499

javac 1.6.0 fails to compile class with inner class

XMLWordPrintable

    • b73
    • 6
    • b27
    • x86
    • linux
    • Not verified

        FULL PRODUCT VERSION :
        [cps@loddont genericsTest]$ java -version
        java version "1.5.0_13"
        Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_13-b05)
        Java HotSpot(TM) Server VM (build 1.5.0_13-b05, mixed mode)


        ADDITIONAL OS VERSION INFORMATION :
        Linux loddont 2.6.22.9-61.fc6PAE #1 SMP Thu Sep 27 18:27:50 EDT 2007 i686 i686 i386 GNU/Linux


        A DESCRIPTION OF THE PROBLEM :
        This appears to occur when you define a class inside a method and there are generic types in the outer class. It appears that they do not pass to the nested class (sorry if thats the wrong terminology for a named class in a method). I believe this is a bug because it used to compile and it seems inconsistent. You can minimally reproduce this by trying to compile this lot:-

        public interface Foo<T> {
          T foo();
        }

        public class Bar<T> implements Foo<T> {
          public T foo() {
            class FooImpl implements Foo<T> {
              public T foo() {
                return null;
              }
            }
            return new FooImpl().foo();
          }
        }

        You get this error with javac/1.6.0_4

        [cps@loddont genericsTest]$ /usr/java/jdk1.6.0_04/bin/javac -d classes src/*
        src/Bar.java:9: incompatible types
        found : java.lang.Object
        required: T
            return new FooImpl().foo();
                                    ^
        1 error

        However, as indicated, java 1.5.0 is quite happy:-

        [cps@loddont genericsTest]$ /usr/java/jdk1.5.0/bin/javac -d classes src/*
        [cps@loddont genericsTest]$

        It seems unlikely that this is the correct behaviour since if the type T is not available in the nested class, then I'd exect the line

            class FooImpl implements Foo<T> {

        to fail to compile because T isn't defined.

        I should mention that the eclipse compiler is quite happy with this construct. Maybe they're wrong but I would still suggest that the javac compiler doesn't make much sense here as the generic type T is clearly visible in some sense.

        STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
        1) Create src dir and classes dir.
        2) Put 'foo.java' and 'bar.java' in src dir.
        3) javac -d classes src/*


        REPRODUCIBILITY :
        This bug can be reproduced always.

        CUSTOMER SUBMITTED WORKAROUND :
        The following modified version of Bar does compile with 1.6.0_4 and 1.5.0 oddly enough

        public class Bar<T> implements Foo<T> {
          public T foo() {
            class FooImpl<T2 extends T> implements Foo<T> {
              public T foo() {
                return null;
              }
            }
            return new FooImpl<T>().foo();
          }
        }

        as does the slightly more sensible version

        public class Bar<T> implements Foo<T> {
          public T foo() {
            class FooImpl<T2> implements Foo<T2> {
              public T2 foo() {
                return null;
              }
            }
            return new FooImpl<T>().foo();
          }
        }

        So you can always make the class external and/or add parameterised types. I was only doing this because the class concerned was never likely to be of use outside the method so it seemed the best place for it.

              mcimadamore Maurizio Cimadamore
              ndcosta Nelson Dcosta (Inactive)
              Votes:
              0 Vote for this issue
              Watchers:
              0 Start watching this issue

                Created:
                Updated:
                Resolved:
                Imported:
                Indexed: