java javac 错误:具有泛型的不可转换类型?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4829576/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 08:13:49  来源:igfitidea点击:

javac error: inconvertible types with generics?

javagenericscompiler-errorsjavac

提问by Jason S

There are several other SO questions talking about generics compiling OK w/ Eclipse's compiler but not javac (i.e. Java: Generics handled differenlty in Eclipse and javacand Generics compiles and runs in Eclipse, but doesn't compile in javac) -- however this looks like a slightly different one.

还有其他一些做题谈论泛型编译OK W / Eclipse的编译器,但不是javac的(即Java的:泛型处理differenlty在Eclipse和javacEclipse中的泛型可以编译和运行,但在javac还不能编译) -但是这看起来就像一个稍微不同的人。

I have an enumclass:

我有一enum堂课:

public class LogEvent {
   public enum Type {
       // ... values here ...
   }
   ...
}

and I have another class with a method that takes in arbitrary objects of types descended from Enum:

我有另一个类,它的方法接受来自Enum以下类型的任意对象:

@Override public <E extends Enum<E>> void postEvent(
    Context context, E code, Object additionalData) 
{
    if (code instanceof LogEvent.Type)
    {
        LogEvent.Type scode = (LogEvent.Type)code;
    ...

This works fine in Eclipse, but when I do a clean built with ant, I am getting a pair of errors, one on the instanceofline, the other on the casting line:

这在 Eclipse 中运行良好,但是当我使用 进行干净的构建时ant,我收到了一对错误,一个instanceof在线上,另一个在铸造线上:

443: inconvertible types
    [javac] found   : E
    [javac] required: mypackage.LogEvent.Type
    [javac]         if (code instanceof LogEvent.Type)
    [javac]             ^

445: inconvertible types
    [javac] found   : E
    [javac] required: com.dekaresearch.tools.espdf.LogEvent.Type
    [javac]             LogEvent.Type scode = (LogEvent.Type)code;
    [javac]                                                  ^

Why does this happen, and how can I get around this problem so it will compile properly?

为什么会发生这种情况,我该如何解决这个问题,以便正确编译?

回答by Jon Skeet

I don't know why it's happening, but a workaround is easy:

我不知道为什么会这样,但解决方法很简单:

@Override public <E extends Enum<E>> void postEvent(
    Context context, E code, Object additionalData) 
{
    Object tmp = code;
    if (tmp instanceof LogEvent.Type)
    {
        LogEvent.Type scode = (LogEvent.Type)tmp;
    ...

It's ugly, but it works...

这很丑陋,但它有效......

回答by Sergei Tachenov

Perhaps it is because you've declared E as something that extends Enum<E>. I can't say I understand it completely, but it looks like it limits the set of types to some subset that can't include LogEvent.Type for some reason. Or maybe it's just a bug in the compiler. I'd be happy if someone could explain it more clearly, but here is what you can do:

也许是因为您已将 E 声明为扩展 Enum<E> 的东西。我不能说我完全理解它,但它似乎将类型集限制为某些子集,由于某种原因不能包含 LogEvent.Type。或者它可能只是编译器中的一个错误。如果有人可以更清楚地解释它,我会很高兴,但您可以这样做:

public <E extends Enum<?>> void postEvent(E code) 
{
    if (code instanceof LogEvent.Type)
    {
        LogEvent.Type scode = (LogEvent.Type)code;
        ...
    }
    ...

This works and it is more elegant than just casting to an Object.

这很有效,而且比仅仅投射到对象更优雅。

回答by WW.

I had a similar problem and upgraded from jdk1.6.0_16 to jdk1.6.0_23 and it went away without any code changes.

我有一个类似的问题,从 jdk1.6.0_16 升级到 jdk1.6.0_23,它没有任何代码更改就消失了。

回答by jonescb

In order to use instanceofboth operands have to inherit/implement the same class/interface.
E just can't be cast to LogEvent.Type

为了使用instanceof两个操作数,必须继承/实现相同的类/接口。
E 只是不能转换为 LogEvent.Type

I don't know what your full method looks like, but this should solve your issue by using interfaces and not Generics.

我不知道你的完整方法是什么样的,但这应该通过使用接口而不是泛型来解决你的问题。

public interface EventType { }
public class LogEvent  {
    public enum Type implements EventType {}
}

public void postEvent(Context context, EventType code, Object additionalData) {
    if(code instanceof LogEvent.Type) {
    }
}