We have a class hierarchy similar to this one:
public class TestDereference {
private static MainInterface mi = new MainInterfaceImpl();
public static void main(String[] args) {
System.out.println(mi.getSubInterface().getField());
}
}
interface MainInterface {
<T extends SubInterface> T getSubInterface();
}
interface SubInterface {
Field getField();
}
class Field {
@Override
public String toString() {
return "Hooray!";
}
}
class SubInterfaceImpl implements SubInterface {
Field f = new Field();
public Field getField() {
return f;
}
}
class MainInterfaceImpl implements MainInterface {
SubInterfaceImpl si = new SubInterfaceImpl();
public <T extends SubInterface> T getSubInterface() {
return (T) si;
}
}
The interfaces actually have more than one implementation but that's not the problem. Compiling this with the Eclipse compiler or Java 1.6 works just fine (as seen on ideone). But if I try to compile this with Java 1.5 (which is one of the requirements of our project) gives the following error:
TestDereference.java:12: test.SubInterface cannot be dereferenced
System.out.println(mi.getSubInterface().getField());
^
Also note that it doesn't happen with JDK 1.6 using -target 1.5
either, only with JDK 1.5
The only cases when this error occurs that I found on the web are related to doing things like this:
double d = 2.0;
d.toString();
where it's obvious what the problem is.
But it my case it should work, since it's clear that getSubInterface()
returns a SubInterface
implementing class that definitely has the getField()
method.
So is this a compiler bug? And what options do I have besides doing mi.<SubInterface>getSubInterface()
every single time (which works, but since Eclipse doesn't mark this as an error, most people on the team forget do it, and most of them use only JDK 1.6 so they don't notice it when compiling with maven/cmd line either)?
Check bug: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5003431
Option one:
SubInterface si = mi.getSubInterface();
si.getField();
Option two:
mi.<SubInterface>getSubInterface().getField()
I guess this is a bug that was fixed in Java6.
Rewriting your main method as follows will make things work in both Java5 and 6:
public static void main(String[] args) {
SubInterface subInterface = mi.getSubInterface();
System.out.println(subInterface.getField());
}
It seems Java5 needs the assignment to properly derive the type T
, even though it's already declared to extends SubInterface
. Java6 handles this correctly and doesn't need the additional assignment.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With