【问题标题】:isInstance & instanceof - Why there's no generic way? [duplicate]isInstance 和 instanceof - 为什么没有通用方法? [复制]
【发布时间】:2013-04-02 05:47:30
【问题描述】:

我了解这两种方法的用途和动机 - isInstance 与 instanceOf 的运行时等效。但是,为什么我们有两种方法? 为什么我们不能有一个适用于这两种情况的 instanceof 关键字的通用实现?

例如,这是目前使用的方式:

1)实例

public Collection<String> extract(Collection<?> coll) {
    Collection<String> result = new ArrayList<String>();
    for (Object obj : coll) {
      if (obj instanceof String) {
        result.add((String) obj);
      }
    }
    return result;
}

2)是实例

public <T> Collection<T> extract(Collection<?> coll, Class<T> type) {
    Collection<T> result = new ArrayList<T>();
    for (Object obj : coll) {
      if (type.isInstance(obj)) {
        result.add((T) obj);
      }
    }
    return result;
}

所以,我的问题是为什么我们不能有一个通用的 instanceof 运算符实现来满足上面的第二个示例,如下所示? (即为什么它不能在运行时解析类型?)

public <T> Collection<T> extract(Collection<?> coll, Class<T> type) {
    Collection<T> result = new ArrayList<T>();
    for (Object obj : coll) {
      if (obj instanceof type) {
        result.add((T) obj);
      }
    }
    return result;
}

【问题讨论】:

  • 没有根本原因无法做到这一点。我认为我们必须要问 James Gosling,为什么他在设计 Java 时不选择这样做以获得权威的答案。
  • 可能是因为他在设计Java的时候没有泛型
  • 有趣的是,这些都不能在这里完全起作用。最好的似乎isAssignableFrom()

标签: java class object rtti


【解决方案1】:

一些背景:

  • instanceof 关键字/语法是 Java 1.0 (IIRC) 的 Java。

  • Class.isInstance 方法是在 Java 1.1 中引入的(根据 javadoc)。

  • 泛型是在 Java 1.5(又名 5.0)中引入的,尽管您不需要泛型来使您的示例工作。


instanceof 的语法是&lt;expr&gt; 'instanceof' &lt;type&gt;。为了支持您的建议,他们必须将其更改为 &lt;expr&gt; 'instanceof' &lt;type&gt; | &lt;expr&gt;。这有几个问题:

  • 它可能会引入语法歧义。 (必须进行全面分析才能确定是否是这种情况。)

  • 它可能会引入语义歧义。这个问题有点晦涩,但是类型名和变量名在不同的命名空间中,所以可以同时拥有一个变量和一个名为Something的类。如果这样做,obj instanceof Something 是指变量还是类?那么obj instanceof Something.class呢?

另一个问题是,这种“增强”对典型程序员编写正确代码的能力几乎没有影响。基本上,这是一个外观变化。因此,进行更改没有真正的理由。


现在我不知道 Java 团队是否考虑过这个选项。 (你得问他们!)。如果他们这样做了,我不知道他们为什么拒绝它。但无论这些问题的答案是什么,Java 都不能以这种方式工作……你只能忍受它。

(如果 Java 9 有另一个“Project Coin”,你可能会提出这个想法,但坦率地说,我不认为它会得到太多支持。许多更有价值的想法都未能成功。)


1) 语法歧义是指语法会变得复杂吗?正如您所展示的,应该可以这样编写解析语法..

没有。我的意思是语法可能是模棱两可的;即,可以以两种不同的方式解析给定的话语,这意味着两种不同的事物。然后,您需要一些额外的规则(除了语法之外)来确定哪个解析是正确的。

2) 如果第二条评论中的名称解析引入语义歧义,为什么不能使用适当的命名空间(变量或类型)来限定名称

问题在于,规范编写者要指定、编译器编写者要实现、程序员要理解这些都是额外的语言复杂性。

真正的好处是什么?只是句法上的“优雅”……当您考虑在各个级别发挥作用以使其“起作用”的特殊规则时,实际上并不像看起来那么优雅。

【讨论】:

  • 感谢您的详细解答! :) 一些后续问题-> 1)通过语法歧义,您是否意味着语法会变得复杂?正如您所展示的那样,应该可以这样编写解析语法。如果读起来模棱两可,为什么这是一个大问题?编译器使用语法... 2)如果第二条注释中的名称解析引入语义歧义,为什么不能用适当的命名空间(变量或类型)限定名称?
猜你喜欢
  • 2018-09-04
  • 2018-11-03
  • 1970-01-01
  • 2015-12-08
  • 1970-01-01
  • 2015-07-14
  • 2012-12-23
  • 2017-01-07
  • 1970-01-01
相关资源
最近更新 更多