instanceof 被认为是不好的做法吗?如果是这样,在什么情况下instanceof仍然更可取?

发布于 2024-08-31 15:55:38 字数 158 浏览 4 评论 0原文

多年来,我一直试图尽可能避免 instanceof。在适用的情况下使用多态性或访问者模式。我想它只是在某些情况下简化了维护......还有其他需要注意的缺点吗?

不过我确实在 Java 库中到处看到它,所以我想它有它的位置?什么情况下比较好?这是不可避免的吗?

Over the years, I've tried to avoid instanceof whenever possible. Using polymorphism or the visitor pattern where applicable. I suppose it simply eases maintenance in some situations... Are there any other drawbacks that one should be aware of?

I do however see it here and there in the Java libraries so I suppose it has its place? Under what circumstances is it preferable? Is it ever unavoidable?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

墨洒年华 2024-09-07 15:55:38

它在 equals 的库存实现中肯定占有一席之地。例如,

public boolean equals ( Object o )
{
  if ( this == o )
  {
     return true;
  }

  if ( ! (o instanceof MyClass) )
  {
    return false;
  }

  // Compare fields
  ...
}

关于instanceof,需要了解的一件有趣的事情是它的LHS 可以为null,在这种情况下,表达式的计算结果为false

It's definitely has its place in a stock implementation of equals. E.g.

public boolean equals ( Object o )
{
  if ( this == o )
  {
     return true;
  }

  if ( ! (o instanceof MyClass) )
  {
    return false;
  }

  // Compare fields
  ...
}

One neat thing to know about instanceof is that its LHS can be null and in that case the expression evaluates to false.

疏忽 2024-09-07 15:55:38

我可以想象一些情况,例如,你有一个库的一些对象,你无法扩展它们(或者这样做会很不方便),也许与你的一些对象混合在一起,所有这些对象都具有相同的基类,一起在一个收藏。
我想在这种情况下,使用 instanceof 来区分对这些对象的某些处理可能会很有用。

同上,在遗留代码的某些维护中,您不能在许多旧类中注入一些新行为,只是为了添加新的小功能或一些错误修复......

I can imagine some cases, for example you have some objects of a library, which you can't extend (or it would be inconvenient to do so), perhaps mixed with some objects of your, all with same base class, together in a collection.
I suppose that in such case, using instanceof to distinguish some processing on these objects might be useful.

Idem in some maintenance of legacy code where you cannot inject some new behavior in lot of old classes just to add a new little feature or some bug fix...

千纸鹤带着心事 2024-09-07 15:55:38

我认为当你绝对需要知道对象的类型时,instanceof 是最好的选择。

一种不好的做法是拥有大量实例,一个挨着另一个,并根据它们调用对象的不同方法(当然是强制转换)。
这可能反映出层次结构需要重新思考,甚至​​可能需要重构。

I think that when you absolutely need to know the type of an object, instanceof is the best option available.

A bad practice would be to have a lot of instanceofs, one next to the other, and according to them call different methods of the objects (of course casting).
This would probably reflect that the hierarchy needs rethinking and probably refactoring.

浊酒尽余欢 2024-09-07 15:55:38

当您处于纯 OO 模型中时,instanceof 绝对是一种代码味道。

但是,如果您没有使用 100% OO 模型,或者需要从外部向其中注入内容,则可以使用 instanceof 或等效项(isXXX()getType() >, ...) 可以有其用途。

一般的“规则”是尽可能避免它,特别是当您控制类型层次结构并且可以使用子类型多态性时。这个想法不是询问对象是什么类型并对其执行某些操作,而是直接或通过访问者(本质上是双重多态性)间接要求对象执行某些操作。

When you are inside a pure OO model, then instanceof is definitely a code smell.

If, however, you are not using a 100% OO model or you need to inject stuff into it from the outside, then instanceof or equivalents (isXXX(), getType(), ...) can have its uses.

The general "rule" would be to avoid it whenever possible, especially when you control the type hierarchy and can use subtype polymorphism for example. The idea is not to ask the object what type it is and do something with it, but rather to ask the object directly or indirectly via a Visitor (essentially double polymorphism) to perform some action.

妳是的陽光 2024-09-07 15:55:38

我同意它可能有难闻的气味。很多实例,特别是在链接在一起的 if 块中,闻起来很糟糕。

有时它的行为方式可能是你意想不到的......我曾经发生过一次:(

Class B extends A
Class C extends A

B b = new B();
C c = new C();

b instanceof B -> true
b instanceof C -> true
c instanceof C -> true
c instanceof B -> true

在我的例子中,这是由于 hibernate 制作代理对象而发生的......但这只是代码依赖于 instanceof 的情况是有风险的)

I agree it can have a bad smell. Lots of instanceof, expecially in a chained together if block, smells of bad.

Sometimes it can behave in ways you would not expect... Something I had happen once:

Class B extends A
Class C extends A

B b = new B();
C c = new C();

b instanceof B -> true
b instanceof C -> true
c instanceof C -> true
c instanceof B -> true

(in my case this happened due to hibernate making proxy objects.... but just a case where code dpending on instanceof is risky)

月野兔 2024-09-07 15:55:38

它可以很好地用作铸造前的健全性检查;除了检查对象的类型是否正确之外,它还检查对象是否不为空。

if (o instanceof MyThing) {
    ((MyThing) o).doSomething(); // This is now guaranteed to work.
} else {
    // Do something else, but don't crash onto ClassCast- or NullPointerException.
}

It can well be used as a sanity check before casting; in addition to checking that your object is of right type, it also does check that it's not null.

if (o instanceof MyThing) {
    ((MyThing) o).doSomething(); // This is now guaranteed to work.
} else {
    // Do something else, but don't crash onto ClassCast- or NullPointerException.
}
机场等船 2024-09-07 15:55:38

如果是创造工厂呢?
例如

public static Cage createCage(Animal animal) {
  if (animal instanceof Dog)
    return new DogHouse();
  else if (animal instanceof Lion)
    return new SteelCage();
  else if (animal instanceof Chicken)
    return new ChickenWiredCage();
  else if (animal instanceof AlienPreditor)
    return new ForceFieldCage();
  ...
  else
    return new GenericCage();
}

How about in the case of a creation factory?
e.g.

public static Cage createCage(Animal animal) {
  if (animal instanceof Dog)
    return new DogHouse();
  else if (animal instanceof Lion)
    return new SteelCage();
  else if (animal instanceof Chicken)
    return new ChickenWiredCage();
  else if (animal instanceof AlienPreditor)
    return new ForceFieldCage();
  ...
  else
    return new GenericCage();
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文