Java 库为什么要这么写?

2021-10-25 21:37:22 +08:00
 monster1priest
我一般都是
int a = getNumber(); if(a >0)…….
但是我看到源码写法很多是
int a; if((a=getNumber()) >0)…….
为什么会这么写?是有什么好处吗
7256 次点击
所在节点    Java
50 条回复
wolfie
2021-10-26 09:43:11 +08:00
简洁啊。

举例不对,这个例子没有任何必要。
cpstar
2021-10-26 09:50:33 +08:00
从编译出的 bytecode 上,这两个没差别,也无所谓性能调优。
都是先 invoke 再 ifgt 。

如果说性能调优,那就是 9#说的问题,局部变量,不需要每次都 invoke——当然编译器也可能自动识别并且加上一个局部变量压栈
yinzhili
2021-10-26 09:56:19 +08:00
一些人原先习惯了其它的编程语言,写 Java 代码的时候就会带上之前的习惯,比如:喜欢用下划线开头的变量名
ipwx
2021-10-26 09:59:37 +08:00
if 这么写就是魔怔了。。。

但是如果换成 while ,这么写就爽了。比如:

int bytesRead;
while ((bytesRead = read(fd)) > 0) {
...
}

对比如果不这么写:

while (true) {
int bytesRead = read(fd);
if (bytesRead <= 0) {
break;
}
...
}

显然前者更简洁。
skinny
2021-10-26 10:02:40 +08:00
可能没什么特殊用意,可能就是写这部分代码的人有一些在 C/C++的不良习惯而已,这写法不是特殊需要在 C/C++也不是推荐写法啊。后面更新维护的人也不会在没有明显问题时去动它,于是就保留了下来。JVM 优化不会这么挫的。说起库源代码违反最佳写法官方推荐写法的多了去了,比如 Python ,就很多问题,但是没人愿意去更新源代码。
clf
2021-10-26 10:08:02 +08:00
有没有可能第二种的 a 作用域只在 if 的括号里,所以这样写。
b0644170fc
2021-10-26 10:13:25 +08:00
我觉得 4 楼说的有理.
cubecube
2021-10-26 10:17:57 +08:00
@aguesuka 的确没有神秘加成, 可能就是程序员的个人习惯了

JMHPerfCondition.conditionInvokeFirst avgt 3 13.930 ± 3.733 ns/op
JMHPerfCondition.conditionInvokeLater avgt 3 13.742 ± 1.632 ns/op

```java
@Benchmark
public int conditionInvokeFirst() {
int a = SpecialCaseTest.getNumber();
if (a > 0) {
return 1;
} else {
return 0;
}

}

@Benchmark
public int conditionInvokeLater() {
int a;
if ((a = SpecialCaseTest.getNumber()) > 0) {
return 1;
} else {
return 0;
}
}
```
MineDog
2021-10-26 10:19:39 +08:00
@546L5LiK6ZOt #9 还有是访问成员变量需要的指令比局部变量多,在保证语义一致的情况下,指令更少,性能更好一点
tobepro
2021-10-26 11:03:42 +08:00
记得以前学嵌入式的时候,听韦东山老师说过,有部分大型开源项目的看着感觉很高大上的代码,其实没什么卵用,单纯就是写代码的人想炫技
streamrx
2021-10-26 11:11:03 +08:00
1
yuchting
2021-10-26 11:44:04 +08:00
其实更吊的写法应该是 if((var a = getNumber()) > 0) ...
可惜没语言支持。
oldshensheep
2021-10-26 11:53:56 +08:00
@yuchting
python 可以
xiang0818
2021-10-26 13:44:11 +08:00
因为是上了年代的程序员写的~
ColinZeb
2021-10-26 15:43:23 +08:00
@yuchting c# 可以 ,还可以顺便判断类型或者是否为空。

if( obj is int a )//判断是否 int 类型 如果是 int 赋值给 int a

if(obj is {})//判断是否非空
ipwx
2021-10-26 15:54:21 +08:00
@yuchting python 3.9


if (a := getNumber()) > 0:
....
newmlp
2021-10-26 15:56:10 +08:00
代码行数少,有限的空间内可以看到更多的逻辑,没其他原因
zhgg0
2021-10-26 16:48:11 +08:00
@newmlp 就是 37 楼说的原因,纯粹就是因为代码行数少。仔细翻下 HashMap 的源码就能验证,我刚验证过。
在 HashMap 源码里面,就拿楼主写的代码来作比方 int a = getNumber(); if(a >0);
1 、如果 a 变量在别的地方早就定义过,那就会被写成 if((a=getNumber()) >0);
2 、如果 a 变量在别的地方没定义过,需要定义,那就会被写成 int a = getNumber(); if(a >0);

1 的情况放 if 里能节省一行,所以放 if 里了; 2 的情况不管是否放 if 里都不能节省一行,所以没放 if 里;仔细翻下源码就发现了。
penguinWWY
2021-10-26 16:50:37 +08:00
@cubecube 优化是后面 Hotspot 干的事情,javac 几乎不做优化
geligaoli
2021-10-26 16:53:19 +08:00
@546L5LiK6ZOt 多线程中,有时这么写是为了避免锁,局部变量之后的操作,不用担心其他线程的影响。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/810481

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX