简体   繁体   English

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

[英]javac error: inconvertible types with generics?

There are several other SO questions talking about generics compiling OK w/ Eclipse's compiler but not javac (ie Java: Generics handled differenlty in Eclipse and javac and Generics compiles and runs in Eclipse, but doesn't compile in javac ) -- however this looks like a slightly different one. 还有其他一些SO问题正在讨论使用Eclipse编译器编译OK的泛型而不是javac(即Java:Generics在Eclipse中处理差异,javacGenerics编译并在Eclipse中运行,但不在javac中编译 ) - 但这看起来很像就像一个略有不同的人。

I have an enum class: 我有一个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 instanceof line, 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? 为什么会发生这种情况,如何解决这个问题以便正确编译?

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... 这很难看,但它有效......

Perhaps it is because you've declared E as something that extends Enum<E>. 也许是因为你宣称E是扩展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. 我不能说我完全理解它,但看起来它将类型集限制为某些子集,由于某种原因不能包含LogEvent.Type。 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: 如果有人能够更清楚地解释它,我会很高兴,但这是你可以做的:

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. 这可以工作,它比仅仅转换为Object更优雅。

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

In order to use instanceof both operands have to inherit/implement the same class/interface. 为了使用instanceof两个操作数都必须继承/实现相同的类/接口。
E just can't be cast to LogEvent.Type 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) {
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM