【问题标题】:Instanceof for generic with <?> or without <?>带有 <?> 或不带 <?> 的泛型的Instanceof
【发布时间】:2013-01-26 08:59:19
【问题描述】:

我对 Java 中的泛型和 instanceof 运算符有疑问。

做这样的instanceof check是不可能的:

if (arg instanceof List<Integer>)  // immposible due to
                                   // loosing parameter at runtime

但是可以运行这个:

if (arg instanceof List<?>)


现在我的问题来了 - arg instanceof List arg instanceof List&lt;?&gt; 之间有什么区别吗?

【问题讨论】:

  • 我认为前者可能会在 IDE 中给您一个警告:“使用原始类型”(取决于您使用的 IDE),而后者不会给您这样的警告。但除此之外,这两个是一样的。泛型实际上只是一个编译器提示,它们会被编译器丢弃。
  • 好的,但是如果我有泛型类class A&lt;T&gt;,据说最好这样做:A&lt;?&gt; tab[] = new A&lt;?&gt;[2],而不是:A tab[] = new A[2],因为在这个例子中,第一个''将至少部分执行类型检查''。
  • 部分?你的意思是,检查添加的对象是否至少是实例对象?这不是类型检查...

标签: java generics instanceof


【解决方案1】:

Java 泛型是由 erasure 实现的,即附加类型信息 (&lt;...&gt;) 在运行时将不可用,但会被编译器擦除。它有助于静态类型检查,但不适用于运行时。

由于instanceof 将在运行时而不是在编译时执行检查,因此您不能在instanceof ... 表达式中检查Type&lt;GenericParameter&gt;

关于您的问题(您可能似乎已经知道通用参数在运行时不可用)ListList&lt;?&gt; 之间没有区别。后者是一个通配符,它​​基本上表示与没有参数的类型相同的东西。这是一种告诉编译器“我知道我不知道这里的确切类型”的方式。

instanceof List&lt;?&gt; 归结为instanceof List - 它们完全相同。

【讨论】:

  • 是的,我非常了解这一点,甚至在我的问题@scarvy 中写了它;)但我的问题是关于其他的 - 仔细阅读
  • 在(应该更仔细阅读)中编辑过 - 我希望现在回答它?
【解决方案2】:

List and List &lt; ? &gt; 不一样,但在这种情况下,当您使用 instanceof 运算符时,它们的含义相同。

instanceof 不能与泛型一起使用,因为泛型在运行时不存储任何类型信息(由于擦除实现)。

这一点通过以下主要方法清除。我已经声明了两个列表(一个是整数类型,另一个是字符串类型)。而 instanceof 对于List and List &lt; ? &gt;

的行为相同
public static void main(String[] args){
    List<Integer> l = new ArrayList<Integer>();
    List<String> ls = new ArrayList<String>();

    if(l instanceof List<?>){
        System.out.print("<?> ");
    }

    if(l instanceof List){
        System.out.print("l ");
    }

    if(ls instanceof List<?>){
        System.out.print("<?> ");
    }

    if(ls instanceof List){
        System.out.print("ls ");
    }
     }

输出是: &lt;?&gt; l &lt;?&gt; ls

在上面的 main 方法中,所有的 if 语句都是 true。所以很明显,在这种情况下List and List&lt;?&gt; 是相同的。

【讨论】:

  • 我不是在询问执行结果——很明显它们是相同的,只是关于规则。 instanceof List&lt;?&gt; 只是一种看起来很漂亮但无所事事的语言吗?
  • 是的,你完全正确。我只是尝试使用示例来强调相同,因为泛型令人困惑,因此有助于检查示例:)
猜你喜欢
  • 1970-01-01
  • 2011-12-27
  • 1970-01-01
  • 2014-12-14
  • 2012-02-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多