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.

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

                Created:
                Updated:
                Resolved:
                Imported:
                Indexed: