Inconvertible types error
Hello,
I have the following classes:
publicabstractclass JETEvent<Eextends Enum><E>>
publicclass FSDEventextends JETEvent<FSDEvent.Subtypes>
now consider the following method
public FSDTransition getTransition(JETEvent<?> event){
if(eventinstanceof FSDEvent){
// Do something
}
// return something
}
This code looks very legitimate to me, but fails to compile with the following message:
inconvertible types
found: jet.util.events.JETEvent<capture#153 of ?>
required: com.cognosense.icc.fsd.events.FSDEvent
if(eventinstanceof FSDEvent){
^
I don't understand why these types are not convertible. Could somebody explain to me what's wrong here?
To me, it looks very much like a simple
List<?> prout =new ArrayList<String>();
ArrayList<String> denver = (ArrayList<String>)prout;
but apparently, it is not. This is extremely confusing.
Thanks for your help.
[1681 byte] By [
npigueta] at [2007-11-27 1:29:56]

# 1
This simpler example
public class Test {
static class Foo<E extends Enum><E>> {}
static class Bar extends Foo<Bar.TYPES> {
static enum TYPES { A, B, C }
}
static void test(Foo<?> foo) {
if (foo instanceof Bar) ;
}
}
which compiles, would suggest that this is basically correct. However that "capture#153 of" is weird. What are you compiling with? Clearly there is something in what you are not showing us that causes the problem.
# 2
Well, of course there are other things, since this is part of a much bigger project, but they are mostly interface implementation declarations, which shouldn't play any role in this case.
I think this is a compiler bug. I'm compiling with Sun's JDK 6 (build 1.6.0-b105) on Ubuntu feisty, with -source=1.5 and -target=1.5 from within netbeans 5.5.
This really looks badly like a compiler bug to me. Can anybody experienced enough with generics and the compiler check if that really is the case?
# 3
Okay, here's a complete example with a lot of empty classes that causes the problem for me:
abstract class JETEvent<E extends Enum><E>> {
}
class FSDEvent extends JETEvent<FSDEvent.SUBTYPE> {
public enum SUBTYPE {
TYPE_A,
TYPE_B
}
}
interface State<T extends Task> {
public Transition<T> getTransition(JETEvent<?> event);
}
class DefaultState<T extends Task> implements State<T> {
public Transition<T> getTransition(JETEvent<?> event) {
return null;
}
}
class FSDState extends DefaultState<FSDTask> {
@Override
public FSDTransition getTransition(JETEvent<?> event) {
if(event == null || ! (event instanceof FSDEvent)) { // <-- doesn't compile
return null;
}
FSDEvent fsdEvent = (FSDEvent)event; // <-- doesn't compile either
return null;
}
}
interface Task<T extends Task> {
}
class FSDTask extends DefaultTask<FSDTask> {
}
class DefaultTask<T extends DefaultTask> implements Task<T> {
}
interface Transition<T extends Task> {
}
class DefaultTransition<T extends Task> implements Transition<T> {
}
class FSDTransition extends DefaultTransition<FSDTask> {
}
the compiler generates the following error:
javac Bug.java
Bug.java:27: inconvertible types
found: JETEvent<capture#608 of ?>
required: FSDEvent
if(event == null || ! (event instanceof FSDEvent)) { // <-- doesn't compile
^
Bug.java:30: inconvertible types
found: JETEvent<capture#870 of ?>
required: FSDEvent
FSDEvent fsdEvent = (FSDEvent)event;
^
2 errors
a workaround to this problem is to cast to event to Object before doing the comparison.
if(event == null || ! ((Object)event instanceof FSDEvent)) { // <-- This compiles
FSDEvent fsdEvent = (FSDEvent)(Object)event; // <-- This now also compiles
I'd really be interested to know whether I made an error somewhere, or if this is a genuine compiler bug.
Nicolas Piguet
Message was edited by:
npiguet
Added another failing cast, plus workaround.
# 4
I just tried your bunch of classes. Compiles fine here. So I assume you have a classpath problem.
# 5
Hmm... what version of the compiler are you using?
# 6
Ok, I withdraw my statement. It compiles fine with eclipse, either 5 or 6.JDK javac does state the errors you have.
# 7
Well ... it has something to do with the kind of generic parameter used for JETEvent. Maybe it's a bug having to do with self-referencing.
I also tried replacing the Enum with Comparable. Using Integer in FSDEvent led to the same error.
The following works for me:public class JETEvent<E extends Enum><?>> { ... }
# 8
I'll try that. However, it still is a compiler bug isn't it? I mean both JETEvent<E extends Enum><E>> is equivalent to JETEvent<E extends Enum><?>>, right? I know for sure that JETEvent<E extends Enum><E>> is correct since it is exactly the pattern used for declaring the Enum.
I'll file a bug on the bug tracker as soon as I'm sure this is a bug.
Message was edited by:
npiguet
# 9
> I'll try that. However, it still is a compiler bug
> isn't it? I mean both JETEvent<E extends Enum><E>>
> is equivalent to JETEvent<E extends Enum><?>>, right?
Well, not exactly. In the first, E refers to itself as argument of Enum. The second only states, that E extends Enum.
> I know for sure that JETEvent<E extends Enum><E>> is
> correct since it is exactly the pattern used for
> declaring the Enum.
Not exactly. In the Enum declaration, the type "inside" is the same like the type "outside", namely Enum.
> I'll file a bug on the bug tracker as soon as I'm
> sure this is a bug.
Maybe at least you get an answer on why it is the way it is.
# 10
I wonder what is the point of these capture numbers in error messages. What useful information do they carry? None AFAICT.
# 11
> > I'll try that. However, it still is a compiler bug
> > isn't it? I mean both JETEvent<E extends Enum><E>>
> > is equivalent to JETEvent<E extends Enum><?>>,
> right?
>
> Well, not exactly. In the first, E refers to itself
> as argument of Enum. The second only states, that E
> extends Enum.
Well, since any enum type E always extends Enum<E>, I can't see any case where these two wouldn't be equivalent.
# 12
bug filed here: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6548436