首页 > 解决方案 > 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

标签: javacastinglong-integerliterals

解决方案


解释

性能方面没有区别。

(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 计算


推荐阅读