isInstance和instanceof - 为什么没有通用的方式?

5

我了解这两者的用途和目的 - isInstance是instanceOf的运行时等效。但是,为什么我们需要两种方式?我们为什么不能有一个通用实现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;
}

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;
}

所以,我的问题是为什么我们不能有一个通用的 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;
}

这并没有根本性的障碍。我认为我们需要问詹姆斯·高斯林在设计Java时为什么没有选择这样做,以获得权威的答案。 - templatetypedef
2
可能是因为在设计Java时,他没有加入泛型的功能。 - Thihara
有趣的是,这些都不完全适用于这里。最好的似乎是 isAssignableFrom() - Aquarius Power
1个回答

4
一些背景:
- instanceof 关键字/语法从Java 1.0开始就存在(如果我没记错的话)。 - Class.isInstance 方法在Java 1.1中引入(根据javadoc)。 - 泛型是在Java 1.5(也称为5.0)中引入的,但你不需要泛型来使你的示例工作。
instanceof 的语法是 'instanceof' 。要支持您的建议,他们必须将其更改为 'instanceof' | 。这有几个问题:
- 它可能会引入语法歧义。(必须进行全面分析才能确定是否存在这种情况。) - 它可能会引入语义歧义。问题有点难以理解,但类型名称和变量名称位于不同的命名空间,因此可能同时拥有名为 Something 的变量和类。如果您这样做,obj instanceof Something 是指变量还是类?而 obj instanceof Something.class 呢?
另一个问题是,这种“增强”对典型程序员编写正确代码的能力几乎没有影响。基本上,这是一种表面上的变化。因此,没有真正的理由进行更改。
现在我不知道Java团队是否考虑过这个选项。(你必须问问他们!)如果他们这样做了,我不知道为什么他们会拒绝它。但是,无论这些问题的答案是什么,Java都不会以这种方式工作...你只能接受它。
(如果Java 9还有另一个“Project Coin”,您可以提出这个想法,但老实说,我不认为它会得到太多支持。许多更有价值的想法都未能获得通过。)
1)在语法歧义方面,您是否意味着语法会变得复杂?如您所示,应该可以写出那种解析语法。
不是。我的意思是,语法可能会产生歧义;即,给定的话语可能被解析为两种不同的方式,意味着两种不同的含义。然后,您需要一些额外的规则(除了语法)来确定哪个解析是正确的。
2)如果第二条评论中的名称解析引入语义歧义,为什么不能用适当的命名空间(变量或类型)限定名称?
问题在于,这是规范编写者、编译器编写者和程序员理解的所有额外语言复杂性。

那么真正的好处是什么呢?只是一点点语法上的“优雅”……实际上,当你考虑到各个层面上涉及的特殊规则时,它并不像看起来那么优雅。


谢谢您详细的回答! :) 一些后续问题 -> 1)通过语法歧义,您是否意味着语法会变得复杂?就像您展示的那样,应该可以以那种方式编写解析语法。如果阅读起来模糊不清,为什么这是一个大问题?编译器使用语法... 2)如果第二个评论中的名称解析引入了语义歧义,为什么不能使用适当的命名空间(变量或类型)限定名称? - nikel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接