Java 泛型代码可以在 eclipse 中编译,但不能在命令行中编译
我知道过去有几个关于在 eclipse 中编译但不在命令行中编译的问题,但我还找不到问题的答案。
特别是,我认为我能够将 eclipse 设置为使用我的系统编译器,但这仍然没有解决问题。
我目前正在检查:“首选项 ->” Java->安装了 JRE。
它只包含一个 JRE,这是我的系统之一。
这里是问题的具体情况
我有一个 java 泛型类,它采用 Enum 类型作为参数,如下所示:
public class MyClass<T extends Enum<T>>
在类内部的某个位置,我将已知的枚举值与 T 的值进行比较。假设我有这个枚举:
public enum OtherEnum{
a,
b
}
然后我测试:
protected void foo(T enumVal){
if(enumVal == OtherEnum.a){
// do something
}
else if(enumVal == OtherEnum.b){
// do something else
}
}
这在 Eclipse 中编译没有问题,但在命令行 javac 中我收到此错误:
不可比较的类型:T 和 OtherEnum
我在使用 java 1.6 变体的两个系统(1.6.0_26 和 1.6.0_16)上尝试过这个。一个是Mac,另一个是linux。它们都给出相同的错误,而 eclipse 编译没有问题。
那么:
如何确定 eclipse 正在使用哪个编译器?
这里到底是什么问题?
谢谢!
I know there have been several questions in the past regarding things that compile in eclipse but not in command line, but I could not find an answer to my problem yet.
In particular, I think that I was able to set eclipse to use my system compiler, but that still did not solve the problem.
I am currently checking under : 'Preferences -> Java -> Installed JREs'.
This contains only one JRE which is my system one.
Here are the specifics of the problem
I have a java generic class that takes as argument an Enum type, like so:
public class MyClass<T extends Enum<T>>
Somewhere inside the class I compare a known enum value with values of T. So for example let's assume I have this enum:
public enum OtherEnum{
a,
b
}
And then I test:
protected void foo(T enumVal){
if(enumVal == OtherEnum.a){
// do something
}
else if(enumVal == OtherEnum.b){
// do something else
}
}
This compiles with no problem in eclipse but in command line javac I get this error:
incomparable types: T and OtherEnum
I tried this on two systems that use variant of java 1.6 (1.6.0_26 and 1.6.0_16). One is a Mac, the other a linux. They both give the same error, while eclipse is compiling away with no problem.
So:
How do I make sure which compiler eclipse is using?
What is even the problem here?
Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
这是一个 javac 错误,已在 JDK 7 中修复。
请参阅 https://bugs。 java.com/bugdatabase/view_bug?bug_id=6548436
This is a javac bug that has been fixed in JDK 7.
See https://bugs.java.com/bugdatabase/view_bug?bug_id=6548436
非常有趣的问题。
以下代码不编译
JLS3#15.21.3 [1] 说
显然,前面的示例看起来像是一个明显的编程错误,因此规范尝试捕获它并提醒程序员。如果 Java 允许这样做的话,就不会有任何麻烦了。该示例的解决方法是将一侧转换为
Object
。回到你的问题,我们需要决定是否可以将
OtherEnum
转换为T
,或者反之亦然。这是一个令人惊讶的困难问题;按照 JLS3#5.5 [2] 的过程,答案是否定的。这取决于
OtherEnum
是否可以转换为Enum
;那么我们可以找到超级类型X=Enum
和Y=Enum
,它们显然是不同的参数化类型。所以cast是非法的。好吧,这样的规范太复杂了,谁心智正常会在意呢?
您可以通过将 1 转换为
Object
来解决此问题,例如(Object)enumVal == OtherEnum.a
Java 7 的行为有所不同,它会编译您的代码。我不知道原因。 Java7 可能引入了一个新的错误。或者它有一个允许代码的新规范(但我们无权访问新规范)。另一种可能性是我误解了术语“可证明不同的参数化类型”;然而,如果没有正式的定义,就可以直观地看出
Enum
和Enum
是不同的。参考
[1] http://java.sun .com/docs/books/jls/third_edition/html/expressions.html#15.21.3
[2] http://java.sun.com/docs/books/jls /third_edition/html/conversions.html#20232
Very interesting question.
The following code doesn't compile
JLS3#15.21.3 [1] says
Apparently the previous example looks like an obvious programming error, so the spec tries to catch it and alert the programmer. There wouldn't have been any trouble is Java wanted to allow it. The workaround for the example is to cast one side to
Object
.Back to your question, we need to decide if
OtherEnum
can be cast toT
, or the other way around. This is a surprisingly difficult question; following the procedure of JLS3#5.5 [2], the answer is no.It comes down to whether
OtherEnum
can be cast toEnum<T>
; then we can find super typesX=Enum<OtherEnum>
andY=Enum<T>
, which are provably distinct parameterized types. So cast is illegal.Well, such specification is too elaborate, who in their right minds would care?
You can work around it by casting one to
Object
, say(Object)enumVal == OtherEnum.a
Java 7 behaves differently, it does compile your code. I don't know the reason. It's possible that Java7 introduces a new bug. Or it has a new spec that allows the code (but we don't have access to the new spec). Another possibility is that I misunderstood the term "provably distinct parameterized types"; however without formal definition, it is intuitive that
Enum<OtherEnum>
andEnum<T>
are distinct.ref
[1] http://java.sun.com/docs/books/jls/third_edition/html/expressions.html#15.21.3
[2] http://java.sun.com/docs/books/jls/third_edition/html/conversions.html#20232
单独的编译器...== 的使用强制进行更严格的编译时检查,因此在 CL 中它强制执行类型比较和错误。在 Eclipse 中,您可以管理编译时的设置并放宽限制。
您可以尝试 Enum.equals(),它可能不会强制执行如此严格的编译时类型比较。只是一个想法。
Separate compilers...The use of == forces a stricter compile time check, therefore in the CL it is enforcing type comparison and erroring. In Eclipse you can manage the settings for the compile time and loosen the restrictions so to speak.
You can try Enum.equals() and it may not enforce such strict compile time type comparison. just a thought.
Eclipse 使用它自己的 java 编译器实现(ECJ),与 javac 无关。
Java 的 Eclipse 编译器:
Eclipse use it's own java compiler implementation(ECJ) that have nothing to do with javac .
Eclipse Compiler for Java :