我想知道在java中使用instanceof运算符的计算代价是多么昂贵,并想知道是否有更好的替代方法
答案 0 :(得分:9)
另一种方法是避免使用instanceof
并正确设计你的类(在OO意义上)。
由于instanceof
运算符具有相应的“instanceof”字节代码指令,因此可能不会有更高效的方法;但这也可能取决于实际JVM的优化方式。
答案 1 :(得分:7)
instanceof
非常快。然而,这通常是设计不佳的一种表现。
它与(成功)演员的表现大致相同,因为它做的事情大致相同。实际上,任务大致相当于“虚拟”方法调用。
在理智的实现上:对于类,只需要获取运行时类并查看固定的偏移量来检查超类(只要你没有为HotSpot提供超过8个类的继承链)。接口有点棘手,但通常最后两个用例适用于缓存的任何特定运行时类。所以这也很快。
答案 2 :(得分:2)
如果你想检查对象是否是某个类的实例(但不是extends
或implements
),那么将这些类与==
进行比较会更快:
o.getClass() == YourClass.class
否则,因为为此特定目的创建了instanceof
关键字,我看不出你怎么能做得更好......
答案 3 :(得分:2)
我假设您实际上已经对您的代码进行了分析,并发现您对instanceof
的使用是非常重要的性能影响?如果没有,你几乎肯定会解决一个不值得你花时间去解决的问题。
如果你所做的只是这样的代码:
if ( something instanceof MyClass ) {
MyClass mySomething = (MyClass) something;
//...
} else {
//exceptional case
}
然后可以先尝试演员,然后让ClassCastException
成为你的“例外情况”:
try {
MyClass mySomething = (MyClass) something;
} catch (ClassCastException cce) {
//exceptional case
}
现在,虽然它可能是过早的优化,但重新考虑您的设计还为时过早。过度使用instanceof
是一种设计气味。一般来说,你应该使用泛型和多态,以减少你使用instanceof
(实际上是强制转换)到(几乎)零的次数。
如果根据对象的类型应该运行不同的代码,请考虑使该代码成为对象的实例方法,并使不同的类型符合接口。
如果您发现自己“知道”某个对象属于某种类型,但您已经做了一些步骤,使编译器忘记了这一事实(例如,您将其置于原始List
),它可能是一般化的候选人。