1L与(长)1的区别

vik*_*ngh 0 java casting literals long-integer

一位同事在 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
Run Code Online (Sandbox Code Playgroud)

Zab*_*uza 5

解释

性能方面没有区别。

(long) 1是一个常量表达式(因为1是直接已知的),因此,根据Java 语言规范 (JLS)的规则,将是一个longafter 编译。

然而,根据我的经验,人们使用long文字和写作1L来提高可读性的情况要普遍得多。


整数文字越界

但是,当您实际将int文字用于32 位整数范围之外的值时,您会看到一些差异。例如:

(long) 100_000_000_000
Run Code Online (Sandbox Code Playgroud)

不会编译,您必须使用long文字并将其添加L到其中。


字节码

考虑以下两个示例片段:

System.out.println((long) 5);

// versus

System.out.println(5L);
Run Code Online (Sandbox Code Playgroud)

现在看看他们的字节码:

0: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
3: ldc2_w #3 // long 5l
6: invokevirtual #5
Run Code Online (Sandbox Code Playgroud)

两者都编译为ldc2_w直接使用的完全相同的代码,将 a 加载long到堆栈上。因此,在运行时不再需要从int到 的显式转换long


JLS

JLS 在第 15 章中解释了这种行为。表达式

某些表达式具有可以在编译时确定的值。这些是常量表达式(第15.28 节)。

其中指出:

常量表达式是表示原始类型值或不会突然完成并且使用以下内容组成的字符串的表达式: [...]

所以这个片段,因为它只包含一个原始文字和一个原始类型的转换,被认为是一个常量表达式,因此将在编译时计算