java - 1L和(长)1的区别
问题描述
一位同事在 PR 中添加了一条评论评论,我们应该使用1L而不是(long)1。我的同事给出的唯一解释是使用和阅读方便1L。所以我的问题是除了可读性之外,1L是否提供其他一些好处?
我的代码
void getUserId() {
assert((long) 1, userService.getUserId())
}
userService.getUserId() returns long value i.e 1
assert() accepts two long object
解决方案
解释
性能方面没有区别。
(long) 1
是一个常量表达式(因为1
是直接已知的),因此,根据Java 语言规范 (JLS)的规则,它已经是long
编译后的。
然而,根据我的经验,人们使用long
字面量和写作1L
来提高可读性的情况要普遍得多。
Int 字面量越界
但是,当您实际将文字用于32 位整数范围int
之外的值时,您会看到一些差异。例如:
(long) 100_000_000_000
不会编译,您必须使用long
文字并将其添加L
到其中。
字节码
考虑以下两个示例片段:
System.out.println((long) 5);
// versus
System.out.println(5L);
现在看看他们的字节码:
0: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
3: ldc2_w #3 // long 5l
6: invokevirtual #5
两者都编译为直接使用的完全相同的代码ldc2_w
,将 a 加载long
到堆栈上。因此,在运行时不再需要int
显式转换。long
捷豹路虎
JLS 在第 15 章中解释了这种行为。表达式:
有些表达式的值可以在编译时确定。这些是常量表达式(§15.28)。
其中指出:
常量表达式是表示原始类型值或字符串的表达式,它不会突然完成并且仅使用以下内容组成:[...]
所以这个片段,因为它只包含一个原始文字和一个原始类型的转换,被认为是一个常量表达式,因此将在 compile-time 计算。
推荐阅读
- cypress - 使用 Angularjs 测试赛普拉斯。nd-model/data-ng-change 中的值问题
- android - 当应用程序被强行杀死时,LifeCycles 被调用
- html - 如何忽略多选的父溢出?
- python - 给定字符串的索引如何恢复相应的单词/标记?
- php - 当文件名包含特殊字符(俄语、中文...)时,SplFileInfo::getSize 不起作用
- haskell - 如何在haskell中反转图形?
- r - 将 data.table(或 data.frame)转换为 yaml,然后返回其原始格式
- javascript - 外部服务器上的 Cookie
- python - 创建一个 css 选择器以单次定位多个 id
- python - pd.read_sql_query 单/双引号格式化