Sun JDK 1.5 无法使用泛型取消引用错误

发布于 2024-10-02 09:52:03 字数 1655 浏览 0 评论 0原文

我们有一个与此类似的类层次结构:

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;
 }
}

接口实际上有多个实现,但这不是问题。使用 Eclipse 编译器或 Java 1.6 编译它效果很好(如 ideone 所示)。但是,如果我尝试使用 Java 1.5(这是我们项目的要求之一)编译它,则会出现以下错误:

TestDereference.java:12: test.SubInterface cannot be dereferenced
                System.out.println(mi.getSubInterface().getField());
                                                     ^

另请注意,使用 -target 1.5 的 JDK 1.6 也不会发生这种情况,仅适用于 JDK 1.5

我在网上发现的发生此错误的唯一情况与执行以下操作有关:

double d = 2.0;
d.toString();

问题所在很明显。

但就我而言,它应该可以工作,因为很明显 getSubInterface() 返回一个 SubInterface 实现类,该类肯定具有 getField() 方法。

那么这是一个编译器错误吗?除了每次执行 mi.getSubInterface() 之外,我还有什么选择(这有效,但由于 Eclipse 不会将此标记为错误,因此团队中的大多数人都忘记了这样做)它,并且大多数人只使用 JDK 1.6,所以他们在使用 maven/cmd 行编译时也没有注意到它)?

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

鲜肉鲜肉永远不皱 2024-10-09 09:52:03

检查错误: https://bugs.java.com/bugdatabase/view_bug?bug_id=5003431

方案一:

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

方案二:

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

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()
帅气称霸 2024-10-09 09:52:03

我猜这是 Java6 中修复的一个错误。

按如下方式重写您的 main 方法将使事情在 Java5 和 6 中工作:

public static void main(String[] args) {
    SubInterface subInterface = mi.getSubInterface();
    System.out.println(subInterface.getField());
}

似乎 Java5 需要分配才能正确派生类型 T,即使它已经声明为扩展 SubInterface >。 Java6 可以正确处理这个问题并且不需要额外的赋值。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文