由于静态方法无法访问,因此可能会导致字节码略小this
。我认为这不会对速度产生任何影响(如果确实如此,那么它可能太小而无法整体上产生影响)。
我将它们设为静态,因为如果可能的话,我通常会这样做。但这就是我。
编辑:这个答案一直被人们低估,可能是因为关于字节码大小的未经证实的断言。所以我实际上会进行测试。
class TestBytecodeSize {
private void doSomething(int arg) { }
private static void doSomethingStatic(int arg) { }
public static void main(String[] args) {
// do it twice both ways
doSomethingStatic(0);
doSomethingStatic(0);
TestBytecodeSize t = new TestBytecodeSize();
t.doSomething(0);
t.doSomething(0);
}
}
字节码(以检索javap -c -private TestBytecodeSize
):
Compiled from "TestBytecodeSize.java"
class TestBytecodeSize extends java.lang.Object{
TestBytecodeSize();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()V
4: return
private void doSomething(int);
Code:
0: return
private static void doSomethingStatic(int);
Code:
0: return
public static void main(java.lang.String[]);
Code:
0: iconst_0
1: invokestatic #2; //Method doSomethingStatic:(I)V
4: iconst_0
5: invokestatic #2; //Method doSomethingStatic:(I)V
8: new #3; //class TestBytecodeSize
11: dup
12: invokespecial #4; //Method "<init>":()V
15: astore_1
16: aload_1
17: iconst_0
18: invokespecial #5; //Method doSomething:(I)V
21: aload_1
22: iconst_0
23: invokespecial #5; //Method doSomething:(I)V
26: return
}
调用static方法需要两个字节码(byteops?):(iconst_0
用于参数)和invokestatic
。
调用非静态方法需要三个:(aload_1
对于TestBytecodeSize
对象,我想),iconst_0
(对于参数)和invokespecial
。(请注意,如果这些不是私有方法,则应invokevirtual
改为私有方法invokespecial
;请参阅JLS§7.7调用方法。)
现在,正如我说的那样,除了invokestatic
需要少一个字节码的事实外,我不希望这两者之间在性能上有任何大的不同。invokestatic
并且invokespecial
应该都比稍快invokevirtual
,因为它们都使用静态绑定而不是动态绑定,但是我不知道它们中的任何一个都比另一个快。我也找不到任何好的参考。我能找到的最接近的是1997年JavaWorld的这篇文章,基本上重述了我刚才所说的内容:
最快的指令很可能是invokespecial
和invokestatic
,因为这些指令调用的方法是静态绑定的。当JVM解析这些指令的符号引用并将其替换为直接引用时,该直接引用可能将包含指向实际字节码的指针。
但是自1997年以来,许多事情发生了变化。
因此,总而言之……我想我仍然坚持我之前说的话。速度不应该是一个选择另一个的原因,因为速度充其量是微优化。