如果私人帮手方法是静态的,那么它们应该是静态的
假设我有一个旨在实例化的类。 我在类中有几个私有的“helper”方法,它们不需要访问任何类成员,并且只对它们的参数进行操作,并返回结果。
public class Example {
private Something member;
public double compute() {
double total = 0;
total += computeOne(member);
total += computeMore(member);
return total;
}
private double computeOne(Something arg) { ... }
private double computeMore(Something arg) {... }
}
是否有任何特定的原因来指定computeOne
和computeMore
作为静态方法 - 或者任何特定的原因?
将它们保持为非静态是最容易的,尽管它们当然可以是静态的而不会造成任何问题。
我更喜欢这样的辅助方法是private static
; 这将使读者清楚他们不会修改对象的状态。 我的IDE也会以斜体显示对静态方法的调用,所以我会知道该方法是静态的,不会看到签名。
它可能会导致稍小的字节码,因为静态方法无法访问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
}
调用静态方法需要两个字节码(字节?): iconst_0
(用于参数)和invokestatic
。
调用非静态方法有三个: aload_1
(对于TestBytecodeSize
对象,我想), iconst_0
(对于参数),和invokespecial
。 (请注意,如果这些都没有私有方法,它会一直invokevirtual
代替invokespecial
;见JLS§7.7调用方法。)
现在,正如我所说,除了invokestatic
需要少一个字节码之外,我不认为这两者之间的性能会有很大差异。 invokestatic
和invokespecial
都应该是比稍快invokevirtual
,因为它们都使用静态绑定,而不是动态的,但我不知道如果任一比其他快。 我也找不到任何好的参考。 我能找到的最接近的是1997年的JavaWorld文章,它基本上重申了我刚才所说的内容:
最快的指令最有可能是invokespecial
和invokestatic
,因为这些指令调用的方法是静态绑定的。 当JVM解析这些指令的符号引用并用直接引用替换它时,该直接引用可能会包含指向实际字节码的指针。
但自1997年以来,许多事情已经改变
所以最后......我想我仍然坚持我之前说过的话。 速度不应该是选择其中一个的理由,因为它最好是一个微型优化。
我个人的偏好是宣布它们是静态的,因为它是一个明确的标志,表明它们是无状态的。
链接地址: http://www.djcxy.com/p/17293.html上一篇: Should private helper methods be static if they can be static
下一篇: What is the lifetime of a static variable in a C++ function?