问题描述
首先,有一点背景(或者如果不感兴趣,可略过一点)。我很恼火和困惑!这应该是一个非常简单的用例,事实上我的代码已经用Eclipse JDT编译器编译了,所以到目前为止我一直在配置Maven以确保执行此操作。虽然它不能用Oracle JDK和OpenJDK编译,但我一直在困扰着我,因为我认为它可能实际上是我的代码的问题,所以我再次研究它。
我想也许这个错误是在JDT编译器中允许它编译的,而不是Oracle JDK和OpenJDK不允许的,我也测试过这两个。原来的代码要复杂得多,所以我很难看清楚问题出在哪里,事实上我很惊讶地发现,在不编译的情况下,这种情况可能会减少很多。
无论是Eclipse JDT编译器还是Oracle JDK和OpenJDK都有一个非常重要的(imho)错误。
$ b
TL; DR
这是相关代码的最小表示。 (任何接口的类型绑定可以被任何接口所替代,并且编译器行为不会改变):
public class Bug< X扩展属性<?,?> &安培;任何> {
}
接口属性< C,S扩展C>扩展PropertyConst< C> {
@Override
public S get();
}
interface PropertyConst< C> {
public C get();
}
interface任何事物{
}
总之,我认为这应该编译得很好,但Oracle JDK 7& 8和OpenJDK 7不同意。它使用Eclipse Juno进行编译。
当使用这两种编译器编译时,上面的代码给出了类似下面的错误,但对JDT编译器来说工作得很好:
Bug.java:3:错误:types PropertyConst<?>和Property 不相容;都定义了get(),但是具有不相关的返回类型
public class Bug< X extends Property<?,?> &安培;任何> {
^
1错误
这没有意义。返回类型显然是相关的,因为引用的两个方法之一必然frickin'覆盖另一个。我几乎99%相信这应该起作用,事实上,最后1%丢失的唯一原因是它只是基本的使用泛型,因为它没有被发现,但是我没有发现有关错误的报告到它。 (不可否认,我并没有努力,因为只是最糟糕的。你甚至可以根据错误报告是否仍然打开来过滤关键字搜索结果吗?呃。)
对我来说最令人困惑的部分是,当你移除即使额外的接口与错误没有任何关系,类型边界为X上的任何东西。
任何人都可以放心吗?任何人都知道存在这个问题的错误报告,或者之前已经有过错误报告,并可以告诉我问题是什么?如果我没有得到任何确凿的答案,我会提交一些错误报告。
编辑:
A几个人已经指出我有一个前向参考误差,< S扩展了C,C> ;.不知道为什么我没有得到这个错误,它甚至在Eclipse中使用JDT进行编译...
无论如何,它仍然不能为我编译OpenJDK 7或Oracle JDK 7/8,所以我修改了问题以消除此问题。
编辑2:
快速检查确认这种前向引用现在在Java 7中是合法的。应该是这样!
编辑3:
我在上发布了错误报告。如果他们被接受,我会在这里发布链接。
显然你应该报告一个javac错误。你可能有更好的运气问一个开放的jdk邮件列表。但它是感恩节...所以...
虽然这不是泛型的基本用法,但它非常复杂。
First, a little background (or skip down a little if not interested). I'm irritated and confused! This should be a pretty simple use case, and indeed my code has been compiling just fine with the Eclipse JDT compiler, so until now I've been configuring Maven to make sure to do this.It's been bothering me too much though that it doesn't compile with the Oracle JDK and OpenJDK, as I thought it may actually have been a problem with my code, so I've looked into it again.
I thought perhaps that the bug was in the JDT compiler for allowing it to compile, not the Oracle JDK and OpenJDK for not allowing it, both of which I've also tested this with. The original code in question was considerably more complicated, so it was much more difficult for me to see where the problem was, and in fact I was very surprised to see the extent to which this could be reduced whilst still not compiling.
Either the Eclipse JDT compiler or the Oracle JDK and OpenJDK have a pretty major (imho) bug.
TL;DR
This is a fairly minimal representation of the code in question. (The type bound of Anything can be replaced by any interface and the compiler behaviour won't change):
public class Bug<X extends Property<?, ?> & Anything> {
}
interface Property<C, S extends C> extends PropertyConst<C> {
@Override
public S get();
}
interface PropertyConst<C> {
public C get();
}
interface Anything {
}
To summarise, I think this should compile just fine, but the Oracle JDK 7 & 8 and OpenJDK 7 disagree. It does compile for me using Eclipse Juno.
When compiled with either of those compilers the code above gives something like the following error, but works just fine with the JDT compiler:
Bug.java:3: error: types PropertyConst<?> and Property<?,?> are incompatible; both define get(), but with unrelated return types
public class Bug<X extends Property<?, ?> & Anything> {
^
1 error
This makes no sense. The return types are obviously related because one of the two methods referenced necessarily frickin' overrides the other. I'm pretty much 99% confident that this should work, in fact the only reason that last 1% is missing is that it's just too basic a use of generics for this to not have been spotted, and yet I found no bug report relating to it. (Admittedly I didn't look to hard because http://bugs.sun.com/ is just the worst. Can you even filter keyword search results by whether a bug report is still open? Ugh.)
The most confusing part for me is that it compiles just fine when you remove the type bounding for Anything on X, even though the extra interface has nothing to do with the error.
Can anybody put my mind at rest? Anyone know of a bug report which exists for this, or has had experience with it before and can tell me what the problem is? If I don't get any conclusive answers I'll file some bug reports.
Edit:
A couple of people have pointed out that I had a forward reference error with <S extends C, C>. Don't know why I wasn't getting this error, it even compiled in Eclipse with the JDT...
Anyway, it still doesn't compile for me with OpenJDK 7 or Oracle JDK 7 / 8, so I modified the question to remove the issue.
Edit 2:
A quick check confirms that this sort of forward reference is now legal in Java 7. As it should be!
Edit 3:
I've posted bug reports on http://bugs.sun.com/. I'll post links here if/when they're accepted.
It's apparently a javac bug you should report. You probably have better luck asking on one of open jdk mailing lists. But it's Thanksgiving so ...
This is not a basic usage of generics though, it's quite complicated.
这篇关于可能的Java编译器错误!程序不会与一些编译器一起编译的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!