1. 概述

在这个教程中,我们将探讨long类型字面表示与使用强制类型转换操作符将int值转换为long值之间的差异。

2. 字面表示

默认情况下,Java将所有整数数值视为int类型。同样,对于浮点数值,默认类型是double

只有当数值尾随字母“L”或“l”时,才会被视为long类型:

long x = 1L;

然而,小写的“l”看起来像数字1。为了避免混淆,建议使用大写字母版本。

我们都知道,每个基本数据类型都有对应的包装类,它提供了不同的方法,并且允许我们在泛型中使用原始值。

得益于Java的自动装箱功能,我们可以直接将字面值赋给包装类引用:

Long x = 1L;

这里,Java会自动将long值转换为Long对象。

此外,当我们使用字面表示定义long值时,它始终被视为long数据类型。

3. 显式类型转换

接下来,让我们看看何时需要使用显式类型转换。简单回顾一下,类型转换运算符将一个类型转换为括号内的定义类型。

3.1. 原始数据类型

要将一个值从一个原始类型转换为另一个,我们需要进行数据类型的拓宽或窄化

此外,要将支持更大数值范围的值转换为更小范围的类型,不需要额外操作:

int x = 1;
long y = x;

但是,如果要将值放入具有较小数值范围的类型中,需要使用显式类型转换:

int x = 1;
byte y = (byte) x;

需要注意的是,如果数值太大以至于无法适应新类型,可能会发生数据溢出

3.2. 包装类

要将不与原始类型相对应的原始类型转换为包装类,可以使用类型转换运算符并利用Java的自动装箱特性:

int x = 1;
Long y = (long) x;

这里,我们首先将int值转换为long值,然后让Java使用自动装箱将long类型转换为Long

4. 常量表达式

现在我们讨论了基础知识,让我们深入了解一下Java如何处理字面值和原始数据类型的转换。

通常,我们使用“常量”来描述在编译后不会改变的值。在类级别上,我们使用staticfinal关键字来定义它们。

然而,除了类常量,Java还识别可以在编译时计算的表达式。这些表达式被称为常量表达式。

根据Java语言规范(JLS),原始数值的字面表示和原始数据类型的转换都被视为常量表达式。

因此,Java对long值的字面表示和将int数据类型显式转换为long的方式处理相同。

6. 1L(long) 1的比较

最后,让我们看看long类型的字面表示与将int值转换为long的区别。

首先,从性能角度看,这两种表达方式没有区别。它们都是常量,会在编译时评估。

此外,我们可以使用例如javap工具编译这两个语句并比较其字节码结果。我们会发现它们是一样的。它们都使用lconst_1long常量推送到栈。

其次,使用字面表示可以提高代码的可读性

最后,使用字面常量定义常量表达式时,值始终为long类型。然而,使用转换运算符时,我们转换的数字是int类型。

因此,以下代码无法编译:

Long x = (long) 123_456_789_101;

尽管我们将值存储在Long数据类型中,但数字123_456_789_101是int类型。代码无效,因为这个数字超出了整数范围。

另一方面,字面表示可以成功编译:

Long x = 123_456_789_101L;

7. 总结

在这篇文章中,我们了解了使用字面表示long值与将int值转换为long的区别。

总结来说,从Java的角度来看,它们都是常量表达式。换句话说,在这两种情况下,实际值都可以在编译时确定。然而,使用数值的字面表示有一些好处,比如提高可读性和防止可能的数据溢出