Java 泛型代码可以在 eclipse 中编译,但不能在命令行中编译

发布于 2024-12-15 07:04:45 字数 970 浏览 3 评论 0原文

我知道过去有几个关于在 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 编译没有问题。

那么:

  1. 如何确定 eclipse 正在使用哪个编译器?

  2. 这里到底是什么问题?

谢谢!

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:

  1. How do I make sure which compiler eclipse is using?

  2. What is even the problem here?

Thanks!

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

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

发布评论

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

评论(4

牵强ㄟ 2024-12-22 07:04:45

这是一个 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

倒带 2024-12-22 07:04:45

非常有趣的问题。

以下代码不编译

    Integer x = null;
    String s = null;
    if(x==s){}   // error: incomparable types

JLS3#15.21.3 [1] 说

如果无法通过强制转换将任一操作数的类型转换为另一个操作数的类型,则会发生编译时错误 (§5.5)

显然,前面的示例看起来像是一个明显的编程错误,因此规范尝试捕获它并提醒程序员。如果 Java 允许这样做的话,就不会有任何麻烦了。该示例的解决方法是将一侧转换为 Object

回到你的问题,我们需要决定是否可以将 OtherEnum 转换为 T,或者反之亦然。这是一个令人惊讶的困难问题;按照 JLS3#5.5 [2] 的过程,答案是否定的。

这取决于 OtherEnum 是否可以转换为 Enum;那么我们可以找到超级类型 X=EnumY=Enum,它们显然是不同的参数化类型。所以cast是非法的。

好吧,这样的规范太复杂了,谁心智正常会在意呢?

您可以通过将 1 转换为 Object 来解决此问题,例如 (Object)enumVal == OtherEnum.a

Java 7 的行为有所不同,它会编译您的代码。我不知道原因。 Java7 可能引入了一个新的错误。或者它有一个允许代码的新规范(但我们无权访问新规范)。另一种可能性是我误解了术语“可证明不同的参数化类型”;然而,如果没有正式的定义,就可以直观地看出 EnumEnum 是不同的。

参考

[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

    Integer x = null;
    String s = null;
    if(x==s){}   // error: incomparable types

JLS3#15.21.3 [1] says

A compile-time error occurs if it is impossible to convert the type of either operand to the type of the other by a casting conversion (§5.5)

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 to T, 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 to Enum<T>; then we can find super types X=Enum<OtherEnum> and Y=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> and Enum<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

眼波传意 2024-12-22 07:04:45

单独的编译器...== 的使用强制进行更严格的编译时检查,因此在 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.

情释 2024-12-22 07:04:45

Eclipse 使用它自己的 java 编译器实现(ECJ),与 javac 无关。

Java 的 Eclipse 编译器:

增量 Java 编译器。作为 Eclipse 构建器实现,它是
基于 VisualAge for Java 编译器发展而来的技术。在
特别是,它允许运行和调试仍然包含的代码
未解决的错误。

Eclipse use it's own java compiler implementation(ECJ) that have nothing to do with javac .

Eclipse Compiler for Java :

An incremental Java compiler. Implemented as an Eclipse builder, it is
based on technology evolved from VisualAge for Java compiler. In
particular, it allows to run and debug code which still contains
unresolved errors.

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