这两个块之间是否存在任何性能差异?
public void doSomething(Supertype input)
{
Subtype foo = (Subtype)input;
foo.methodA();
foo.methodB();
}
VS
public void doSomething(Supertype input)
{
((Subtype)input).methodA();
((Subtype)input).methodB();
}
这两者之间的任何其他考虑或建议?
答案 0 :(得分:30)
嗯,编译后的代码可能在第二种情况下包括演员两次 - 所以理论上它做了两次同样的工作。但是,智能JIT很可能会计算出您在同一个值上进行相同的转换,因此它可以缓存结果。但 必须至少做一次工作 - 毕竟,它需要决定是否允许演员表成功,或者抛出异常。
与以往一样,如果你关心性能,你应该测试和分析你的代码 - 但我个人会使用第一个表单,只是因为它看起来更具可读性。
答案 1 :(得分:8)
是。必须对每个铸件进行检查以及实际的铸造机制,因此多次铸造将比铸造一次花费更多。但是,这是编译器可能优化的类型。它可以清楚地看到输入自上次演员后没有改变它的类型,并且应该能够避免多次演员 - 或者至少避免一些演员检查。
在任何情况下,如果您真的 担心效率,我会怀疑Java是否是您应该使用的语言。
就个人而言,我会说要使用第一个。它不仅更具可读性,而且以后更容易更改类型。您只需在一个地方更改它,而不是每次在该变量上调用函数。
答案 2 :(得分:2)
我同意Jon的评论,做一次,但是从我记忆中的“铸造昂贵”的一般性问题来看它的价值是什么:Java 1.4使用Java 5显着改进了这一点,使得演员阵容非常便宜。除非你正在编写一个游戏引擎,否则我不知道它是否会让人烦恼不已。我更担心自动装箱/拆箱和隐藏物品的创建。
答案 3 :(得分:1)
根据this article,与投射相关的费用。
请注意,该文章是从1999年开始的,由读者决定信息是否仍然值得信赖!
答案 4 :(得分:-4)
在第一种情况下:
Subtype foo = (Subtype)input;
它是在编译时确定的,所以在运行时没有成本。
在第二种情况下:
((Subtype)input).methodA();
它是在运行时确定的,因为编译器不会知道。 jvm必须检查它是否可以转换为Subtype
的引用,如果不是ClassCastException
等等。所以会有一些费用。