-
Bug
-
Resolution: Fixed
-
P3
-
6
Issue | Fix Version | Assignee | Priority | Status | Resolution | Resolved In Build |
---|---|---|---|---|---|---|
JDK-8043524 | 6u85 | Dmeetry Degrave | P3 | Resolved | Fixed | b01 |
JDK-2158770 | OpenJDK6 | Joe Darcy | P3 | Resolved | Fixed | b13 |
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.
[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.
- backported by
-
JDK-2158770 javac 1.6.0 fails to compile class with inner class
- Resolved
-
JDK-8043524 javac 1.6.0 fails to compile class with inner class
- Resolved
- relates to
-
JDK-5009484 Compiler fails to resolve appropriate type for outer member
- Closed
-
JDK-6865519 Incorrect unchecked warning involving local class
- Closed