57

以下编译良好:

  Object o = new Object();
  System.out.println(o instanceof Cloneable);

但这不会:

  String s = new String();
  System.out.println(s instanceof Cloneable);

抛出编译器错误。

问题是什么?

4

3 回答 3

157

我最近遇到的一个相关问题(在我弄清楚发生了什么之前,这导致我访问了这个页面)是 Eclipse 环境可以错误地在“instanceof”表达式中报告“不兼容的条件操作数类型”,原因是缺少“instanceof”右侧类型的“import”语句。我花了一段时间试图弄清楚有问题的类型如何可能不兼容,然后才发现缺少导入导致了整个问题。希望这些信息可以节省一些时间。

于 2012-01-04T19:10:14.263 回答
57

您的问题的一个更明显的体现如下:

if ("foo" instanceof Number)
   // "Incompatible conditional operand types String and Number"

这在JLS 15.20.2 类型比较运算符instanceof中指定:

RelationalExpression:
       RelationalExpression instanceof ReferenceType

如果将RelationalExpression转换为ReferenceType将作为编译时错误被拒绝,则instanceof关系表达式同样会产生编译时错误。在这种情况下,instanceof表达式的结果永远不会是真的。

也就是说,由于此转换表达式会生成编译时错误:

(Number) "foo"

这个表达式也必须如此:

("foo" instanceof Number)

你的情况有点微妙,但原理是一样的:

  • String是最后一堂课
  • String不执行Cloneable
  • 因此你不能做(Cloneable) aString
  • 因此你也不能做aString instanceof Cloneable
于 2010-03-31T09:41:18.420 回答
30

编译器知道这String是一个最终类并且没有实现Cloneable. 所以 String 的任何实例不能是Cloneable. 它阻止你认为你有一个有意义的测试,而实际上它总是会打印“假”。

于 2010-03-31T08:12:13.450 回答