为什么我会得到“instanceof的非法通用类型”? [英] Why do I get "Illegal generic type for instanceof"?

查看:462
本文介绍了为什么我会得到“instanceof的非法通用类型”?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

鉴于:

  public class C< T> {
private class D {
public boolean equals(Object o){
if(!(o instanceof D))// line 4
return false;
D other =(D)o; //第6行
返回i == other.i;
}
int i;
}
}

我得到:

  C.java:4:instanceof的非法泛型类型
if(!(o instanceof D))
^

我也会在第6行收到一个unchecked cast警告。为什么? o 不是一个泛型类型 - 它只是一个普通的 Object 。如何通过检查并转换为 D

的实例来正确实现 equals()

注意:显然,这个代码示例是我的实际代码的削减版本。真正的类 C D 大得多, D 是其实现使用的私有内部类 C



FYI:真正的 D 确实使用了通用参数 T

解决方案


o不是一个泛型类型 - 它只是一个普通的Object。


这不是问题。问题......和两个编译错误的根本原因......是 D 是一个泛型类。它是通用的,因为它是泛型类中的非静态嵌套类。其完全合格的名称将是 some.pkg.C .D


FYI:真正的D确实使用了泛型参数T。


事实上它可以 em>使用 T 是使 D 泛型类的原因。



不能使用 instanceof D (D)的原因是泛型类型的擦除。基本上,运行时无法区分(比如说) C< String> .D< $ $ c>和< code> C< Integer> .D 。由于它不能这样做,它不能确定 instanceof D 是否应该返回 true false 或者(D)应该成功或抛出 ClassCastException



一种解决方案是将 D 声明为静态。但是这不适用于你的真正的D,因为静态类不能使用封闭类中的泛型类型参数。你的FYI表示它这样做。



另一个解决方案是实例化外部类 C ,将它传递给作为 java.lang.Class< T> 实例的实际类型 T 。然后使用这个 Class 实例来实现运行时类型检查并根据需要强制转换。这可能是混乱的。



第三个解决方案是仔细分析代码并确定它是否对@SuppressWarning注释安全抑制不安全的转换等警告。


什么类型的擦除? 'o'直接是Object类型。


其实 Object 类型的 o 变量。实际的对象很可能有其他类型,并且它是 类型(例如,如果它是 D 实例)将会是受到类型擦除。

Given:

public class C<T> {
    private class D {
        public boolean equals( Object o ) {
            if ( !(o instanceof D) )    // line 4
                return false;
            D other = (D)o;             // line 6
            return i == other.i;
        }
        int i;
    }
}

I get:

C.java:4: illegal generic type for instanceof
          if ( !(o instanceof D) )
                              ^

I also get an "unchecked cast" warning about line 6. Why? The o is not a generic type -- it's just a plain Object. How can I correctly implement equals() by both checking for and casting to an instance of D?

Note: Obviously, this code example is a whittled-down version of my actual code. The real classes for C and D are much larger and D is a private inner class of C used by its implementation.

FYI: The real D does make use of the generic parameter T.

解决方案

The o is not a generic type -- it's just a plain Object.

That's not the problem. The problem ... and the root cause of both compilation errors ... is that D is a generic class. And it is generic because it is a non-static nested class in a generic class. Its fully qualified name would be some.pkg.C<T>.D.

FYI: The real D does make use of the generic parameter T.

And the fact that it could make use of T is what makes D a generic class.

The reason that you cannot use instanceof D or (D) is generic type erasure. Basically, the runtime cannot distinguish between the types of (say) C<String>.D and C<Integer>.D. And since it cannot do that, it cannot determine if instanceof D should return true or false or if (D) should succeed or throw ClassCastException.

One solution would be to declare D as static. But that will not work with your "real D" because a static class cannot make use of a generic type parameter from the enclosing class(es). Your "FYI" says that it does that.

Another solution is to instantiate the outer class C passing it the actual type of T as a java.lang.Class<T> instance. Then use this Class instance to implement the runtime type checks and casts as required. This is likely to be messy.

The third solution is to carefully analyze the code and determine if it is safe to a @SuppressWarning annotations to suppress the "unsafe cast" etc warnings.

What type erasure? 'o' is of type Object directly.

Actually Object is the declared type of the o variable. The actual object will most likely have some other type, and it is that type that (if it is a D instance for example) will have been subjected to type erasure.

这篇关于为什么我会得到“instanceof的非法通用类型”?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆