Search code examples
javagenericsjava-5

Sun JDK 1.5 cannot dereference error with generics


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)?


Solution

  • Check bug: https://bugs.java.com/bugdatabase/view_bug?bug_id=5003431

    Option one:

    SubInterface si = mi.getSubInterface();
    si.getField();
    

    Option two:

    mi.<SubInterface>getSubInterface().getField()