我要问的是这样做是否有区别:
public Something importantBlMethod(SomethingElse arg) {
if (convenienceCheckMethod(arg)) {
// do important BL stuff
}
}
private boolean convenienceCheckMethod(SomethingElse arg) {
// validate something
}
而且:
public Something importantBlMethod(SomethingElse arg) {
if (convenienceCheckMethod(arg)) {
// do important BL stuff
}
}
private static boolean convenienceCheckMethod(SomethingElse arg) {
// validate something
}
我实际上使用选项1,因为它对我来说似乎更自然。
第一种和第二种方式之间是否有样式/约定/性能差异?
谢谢,
正如我在测试中所建议的那样,在我的基准测试中,动态方法更快。
这是测试代码:
public class Tests {
private final static int ITERATIONS = 100000;
public static void main(String[] args) {
final long start = new Date().getTime();
final Service service = new Service();
for (int i = 0; i < ITERATIONS; i++) {
service.doImportantBlStuff(new SomeDto());
}
final long end = new Date().getTime();
System.out.println("diff: " + (end - start) + " millis");
}
}
这是服务代码:
public class Service {
public void doImportantBlStuff(SomeDto dto) {
if (checkStuffStatic(dto)) {
}
// if (checkStuff(dto)) {
// }
}
private boolean checkStuff(SomeDto dto) {
System.out.println("dynamic");
return true;
}
private static boolean checkStuffStatic(SomeDto dto) {
System.out.println("static");
return true;
}
}
对于100000次迭代,动态方法传递577ms,静态615ms。
然而,这对我来说是不确定的,因为我不知道编译器何时以及何时决定优化。
这是我想要找到的。
答案 0 :(得分:7)
表现明智:差异(如果有的话)可以忽略不计。
经验法则是如果方法不与其类的任何成员交互,则声明您的方法是静态的。
答案 1 :(得分:2)
如果您的方法需要实例数据或调用其他实例方法,则必须是实例方法。
如果函数 only 依赖于它的参数,而没有其他静态数据,那么它也可能是一个实例方法 - 你可以避免在调用时重复类名静态功能。
恕我直言,除非:
,否则不需要制作函数static
private
)和答案 2 :(得分:2)
如果函数的结果不依赖于除参数之外的任何东西,它应该是静态的。如果它依赖于实例,请将其设为实例成员。
这不是关于表现;这是关于语义的。除非你每秒钟调用这个函数一百万次,否则你不会注意到性能差异,即使这样,差异也不会很大。
答案 3 :(得分:2)
这完全取决于具体情况。通常,静态方法/变量在类中声明,以便外部类可以使用它们。
如果要调用本地方法,那么通常应该使用实例方法而不是静态调用。
仅供参考,您从实例方法调用静态方法的语法是错误的。你必须提供班级名称。
答案 4 :(得分:2)
据我所知 NO 静态方法的绑定与非静态私有绑定相同,即early binding
。
。
编译器实际上在为代码添加方法代码(静态或非静态私有)时创建它的字节代码。
更新:刚刚通过此article。它说实例方法绑定是dynamic
所以如果方法不是non-static private
那么。 静态方法更快。
答案 5 :(得分:2)
可能,它可能不会。不同的代码执行可能会有所不同。
如果不深入研究Hotsport代码(或非Hotspot JVM的代码),这是唯一可以知道的东西:
这两个操作码都有一个解析实际调用方法的过程,这些过程相对类似(你可以阅读规范)。如果不计算实际实现的指令,就不可能说哪个更快。
invokespecial
将额外的值推入堆栈。这样做的时间以几纳秒计算。
尽管如此,Hotspot还是可以进行各种优化。在程序运行期间,它可能不必多次执行实际的方法解析。它可能会选择内联方法(或者可能不会),但是这个成本将再次大致相当。
答案 6 :(得分:1)
我查了一下,我希望它可以做你想知道的,代码不会很漂亮:
public class main {
@SuppressWarnings("all")
public static void main(String[] args) {
main ma = new main();
int count = Integer.MAX_VALUE;
long beg = (new Date()).getTime();
for (int i = 0; i < count; i++) {
ma.doNothing();
}
System.out.println("priv : " + new Long((new Date()).getTime() - beg).toString());
beg = (new Date()).getTime();
for (int i = 0; i < count; i++) {
doNothingStatic();
}
System.out.println("privstat : " + new Long((new Date()).getTime() - beg).toString());
}
private void doNothing() {
int i = 0;
}
private static void doNothingStatic() {
int i = 0;
}
}
结果:
priv:1774
privstat:1736
priv:1906年 privstat:1783
priv:1963年 privstat:1751
priv:1782
privstat:1929年
它看起来不像静态 - 非静态私有方法。我确信这些差异来自当前的机器负担。
答案 7 :(得分:1)
我参与编码竞赛,我观察到,非静态方法比静态方法更快(但是最小)。当然,这取决于您的使用情况和情况需求,但静态方法与非静态方法相比性能较差。按照惯例,您可以使用静态方法来简化代码,但创建类的实例并调用该方法将提供更好的性能。