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.

xolotla at 2007-7-12 0:30:13 > top of Java-index,Core,Core APIs...
# 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?

npigueta at 2007-7-12 0:30:13 > top of Java-index,Core,Core APIs...
# 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.

npigueta at 2007-7-12 0:30:13 > top of Java-index,Core,Core APIs...
# 4
I just tried your bunch of classes. Compiles fine here. So I assume you have a classpath problem.
stefan.schulza at 2007-7-12 0:30:13 > top of Java-index,Core,Core APIs...
# 5
Hmm... what version of the compiler are you using?
npigueta at 2007-7-12 0:30:13 > top of Java-index,Core,Core APIs...
# 6
Ok, I withdraw my statement. It compiles fine with eclipse, either 5 or 6.JDK javac does state the errors you have.
stefan.schulza at 2007-7-12 0:30:13 > top of Java-index,Core,Core APIs...
# 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><?>> { ... }

stefan.schulza at 2007-7-12 0:30:13 > top of Java-index,Core,Core APIs...
# 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

npigueta at 2007-7-12 0:30:13 > top of Java-index,Core,Core APIs...
# 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.

stefan.schulza at 2007-7-12 0:30:13 > top of Java-index,Core,Core APIs...
# 10
I wonder what is the point of these capture numbers in error messages. What useful information do they carry? None AFAICT.
xolotla at 2007-7-12 0:30:13 > top of Java-index,Core,Core APIs...
# 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.

npigueta at 2007-7-12 0:30:13 > top of Java-index,Core,Core APIs...
# 12
bug filed here: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6548436
npigueta at 2007-7-12 0:30:13 > top of Java-index,Core,Core APIs...