Java 9 整数转字符串的类型转换

8

我刚刚了解到Java 9的一个特性https://bugs.openjdk.java.net/browse/JDK-8085796,它表示使用StringBuilder进行“慢速”字符串连接的速度将得到提升。

所以我的问题是,是否仍然存在以下方式将int转换为String的缺点?

int i = 16;
String s = ""+i;

将int强制转换为String,使用Integer.toString(i)String.valueOf(i)有什么优缺点吗?

编辑:由于我的问题过于主观(抱歉),我进行了修改。我对不同强制转换方式的正面或负面方面很感兴趣。每个人都应该决定自己使用哪种方式。


15
更短了,是的。更容易理解吗?我不这么认为。Integer.parseInt 是个误导,因为它是相反方向的 - String.valueOf(i) 很明确地表达了它在做什么。你的目标不是执行字符串连接,那么为什么你的代码会包含字符串连接呢? - Jon Skeet
1
“更易理解”是主观的。 - shmosel
2
@PeterLawrey: 我猜我们可能不同意。我对 Integer.toString 没有问题 - 这两个方法都表达了它们想要做的事情,而 String.valueOf 的优点是你可以用它来处理所有类型。 - Jon Skeet
2
我认为仍然存在一个缺点:你的代码看起来像是在进行字符串拼接,但实际上你想要获取一个值的字符串表示。 - Jon Skeet
5
我不认为字符串拼接,即使通过代码的优化(如indyfication)在将来允许更好的策略,也能比将整数转换为字符串(例如使用Integer.toString())更快,因为它仍然需要进行转换,然后再与空字符串连接。最多,它可以检测到这个丑陋的习惯用法,并将其转换为Integer.toString()。但我同意Jon Skeet的观点:Integer.toString清晰地表达了意图。 - JB Nizet
显示剩余3条评论
1个回答

6
首先,认为Integer.toString(i)总是比""+i更快这一假设不成立。
特别要注意的是,如果i是一个编译时常量,那么""+i也是一个编译时常量,这与String.valueOf(i)相反。当然,如果定义像final int i=16;这样,读者会反对使用""+i,因为"16"会更清晰。但是如果我们谈论的是final int DEFAULT_USER = DEFAULT_GROUP << GROUP_BIT;""+DEFAULT_USER比包含实际数字的字面字符串更加清晰。而且作为编译时常量不仅仅是性能问题,它还允许在注释或switch语句的case标签中使用该字符串。
如果i不是编译时常量,则没有强制编译形式,因此原则上编译器允许将""+i编译成Integer.toString(i)。如果我们将通常的朴素(或者称之为“直截了当”)实现new StringBuilder().append("").append(i).toString()Integer.toString(i)变体或虚构的优化Java 9实现进行比较,只有从StringBuilder的缓冲区到结果String的值数组的最终复制操作可能会产生性能影响,但这可以被HotSpot JVM优化掉。Java 9解决方案的另一个问题,即StringBuilder的初始容量,在这里不相关,因为int的字符串表示很容易适合默认容量16char
对于大多数复杂的int值,转换为十进制形式的成本将明显超过其他成本,因此,如果你更喜欢""+i而不是Integer.toString(i),则不应该让性能考虑成为不使用它的原因。这也意味着您不应该期望使用Java 9实现会产生极大的加速。主要操作仍然是相同的。
我认为,Java 9解决方案的最大改进是减少代码大小,因为针对每个字符串连接表达式生成的所有类似调用序列都将折叠为一条指令(这对于多个表达式的连接尤其重要)。提高性能的机会只是一个不错的附加功能,但我不会期望在JRE 9的第一个版本中会有显著的改进。
因此,在""+iInteger.toString(i)String.valueOf(i)之间做出决策仅仅是一个风格问题(我们在这里不讨论),而不是性能问题。

编译时常量确实非常有趣。非常感谢您提供如此详细的答案。 - Mein Name

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接