isInstance&instanceof - 为什么没有通用方法?

nik*_*kel 5 java class object rtti

我理解这两者的用法和动机 - isInstance是instanceOf.But的Runtime Equivalent,为什么我们有两种方法呢?为什么我们不能有一个适用于这两种情况的instanceof关键字的通用实现?

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

1)的instanceof

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;
}
Run Code Online (Sandbox Code Playgroud)

2)isInstance

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;
}
Run Code Online (Sandbox Code Playgroud)

所以,我的问题是为什么我们不能有一个适用于上面第二个例子的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;
}
Run Code Online (Sandbox Code Playgroud)

Ste*_*n C 4

一些背景:

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

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

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


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

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

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

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


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

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


1)通过语法歧义你的意思是语法会变得复杂?正如你所表明的,应该可以这样编写解析语法。

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

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

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

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