【问题标题】:instanceof yields inconsistent results for detecting interfaces?instanceof 检测接口产生不一致的结果?
【发布时间】:2009-03-10 16:28:54
【问题描述】:

关于instanceof,我应该知道什么棘手的事情吗?我通过一些方法传递了一个对象列表,并测试这些对象是否使用instanceof 实现了特定的接口。在某些情况下,instanceof 正确地将对象识别为实现了接口,而在其他情况下则没有。它似乎给我在不同地方的同一个对象上不一致的结果。这里有什么技巧/陷阱我应该注意的吗?

期待您可能拥有的 cmets:

1) 我知道instanceof 是不好的形式。我正在使用无法更改的不太完美的对象层次结构,这是我能想到的最不坏的事情。

2) 我正在创建一个代码示例,但如果我要在此处粘贴任何有用的内容,我需要大量简化我的代码。同时,如果您以前看过此内容并且可以有所启发,请这样做。

【问题讨论】:

  • 有机会获得代码示例吗?
  • 只是一个猜测,但很可能简化代码以发布示例可能会暴露问题。 instanceof 是一个运算符,因此它应该始终以相同的方式工作。
  • 是的,我的猜测是,如果我将代码简化到足以粘贴给所有有帮助的人,我会找到错误并且不需要:)
  • 为什么说使用instanceof是不好的形式?

标签: java instanceof


【解决方案1】:

您是否正在动态加载任何类型,可能来自不同的类加载器?唯一一次我看到明显不一致的结果是当我有两行代码时,看起来它们引用了相同的类型,但实际上是从不同的类加载器加载了该类型。

【讨论】:

  • 天哪,我不这么认为。运行一个简单的 junit 测试用例时会出现奇怪的情况。这给了我足够的信息来假设我做了一些愚蠢的事情,只需要简化。谢谢。
【解决方案2】:

instanceof 总是为null 返回false。如果左边的静态类型不可能是指定类型的实例,则它不会编译。除此之外,它应该毫无意外地起作用。

与 C++(我相信 Smalltalk)不同,对象不能在运行时更改类型。在 C++ 中,类型在构造过程中发生变化,因此无法从构造函数调用方法到派生类 [子类] 方法。

【讨论】:

    【解决方案3】:

    好的,问题解决了。像往常一样,这个问题没有我想象的那么奇怪。我正在从事的项目不幸的是有一些重复的类名。我正在使用 foo.MyInterface 创建类并测试 bar.MyInterface 的实例。感谢您的回复。它确实帮助我想通了。

    【讨论】:

    • 具有讽刺意味的是,我几乎将这种可能性包含在我的回答中,但由于某种原因最终没有。这会教我 - 下次我会发布所有想法,无论多么愚蠢:)
    • 感谢您回答自己的问题,这也是我的愚蠢错误!
    【解决方案4】:

    我知道的唯一问题是 nullinstanceof 没有类型。

    【讨论】:

    • 我在这里有一个令人难以置信的实现时刻。
    【解决方案5】:

    只要您没有类加载问题,instanceof 就可以始终如一地工作。 我猜你知道如果 A 继承自 B,或者 A 实现的某些接口或 A 扩展的类是 instanceof B,则 A instanceof B 返回 true。

    如果在您期望为 true 时得到 false,您可能正在尝试比较来自不同 ClassLoader 的实例。

    【讨论】:

      【解决方案6】:

      您可能想要“isAssignable”而不是 instanceof:

      if (MyInterface.isAssignableFrom(myObject.getClass())) {
        //  do work here
      }
      

      这将为实现您的接口的类返回 true。

      【讨论】:

      • 与instanceof完全一样,但如果myObject为null则抛出NPE。
      • ...最好使用 MyInterface.class.isInstance(myObject) - 这不会引发 NPE。如果您在编译时知道 MyInterface,即使这是毫无意义的 - 不妨使用 instanceof
      猜你喜欢
      • 2012-01-16
      • 1970-01-01
      • 2017-06-10
      • 1970-01-01
      • 2014-06-03
      • 2021-09-06
      • 2017-08-18
      • 1970-01-01
      • 2021-11-01
      相关资源
      最近更新 更多