类型转换
编辑类型转换
编辑类型转换将原始类型的值转换为目标类型的等效值。隐式类型转换推断目标类型,并在某些操作期间自动发生。显式类型转换指定目标类型,并强制作为其自身的操作发生。使用类型转换运算符 '()'
来指定显式类型转换。
有关所有允许的类型转换的快速参考,请参阅类型转换表。
错误
- 如果在类型转换期间,目标类型不存在等效的值。
- 如果给出了隐式类型转换,但需要显式类型转换。
语法
cast: '(' TYPE ')' expression
示例
-
有效的类型转换。
数值类型转换
编辑数值类型转换将原始数值类型的值转换为目标数值类型的等效值。当原始数值类型的值大于目标数值类型可以容纳的值时,两个数值类型值之间的转换会导致数据丢失。整数类型值和浮点类型值之间的转换可能会导致精度损失。
下表中以行的形式显示了每种数值类型的值所允许的转换
byte |
short |
char |
int |
long |
float |
double |
|
byte |
隐式 |
隐式 |
隐式 |
隐式 |
隐式 |
隐式 |
|
short |
显式 |
显式 |
隐式 |
隐式 |
隐式 |
隐式 |
|
char |
显式 |
显式 |
隐式 |
隐式 |
隐式 |
隐式 |
|
int |
显式 |
显式 |
显式 |
隐式 |
隐式 |
隐式 |
|
long |
显式 |
显式 |
显式 |
显式 |
隐式 |
隐式 |
|
float |
显式 |
显式 |
显式 |
显式 |
显式 |
隐式 |
|
double |
显式 |
显式 |
显式 |
显式 |
显式 |
显式 |
示例
-
有效的数值类型转换。
-
导致错误的无效数值类型转换。
引用类型转换
编辑引用类型转换将原始引用类型的值转换为目标引用类型的等效值。当原始引用类型是目标类型的后代时,允许两个引用类型值之间的隐式转换。当原始类型是目标类型的后代,或者目标类型是原始类型的后代时,允许两个引用类型值之间的显式转换。
示例
-
有效的引用类型转换。
声明
List x
;将默认值null
存储到x
声明
ArrayList y
;分配ArrayList
实例 →ArrayList 引用
;将ArrayList 引用
存储到y
;从
y
加载 →ArrayList 引用
;将ArrayList 引用
隐式转换为List 引用
→List 引用
;将List 引用
存储到x
;(请注意,ArrayList
是List
的后代)从
x
加载 →List 引用
;将List 引用
显式转换为ArrayList 引用
→ArrayList 引用
;将ArrayList 引用
存储到y
;从
y
加载 →ArrayList 引用
;将ArrayList 引用
显式转换为List 引用
→List 引用
;将List 引用
存储到x
;(请注意,显式转换是多余的,隐式转换是有效的) -
导致错误的无效引用类型转换。
声明
List x
;分配ArrayList
实例 →ArrayList 引用
;将ArrayList 引用
隐式转换为List 引用
→List 引用
;将List 引用
存储到x
声明
ArrayList y
;从x
加载 →List 引用
;错误 → 无法将List 引用
隐式转换为ArrayList 引用
;(请注意,由于ArrayList
是List
的后代,因此显式转换有效)声明
ArrayList y
;从x
加载 →List 引用
;错误 → 无法将List 引用
显式转换为Map 引用
;(请注意,由于List
和Map
都不是对方的后代,因此任何转换都无效)
动态类型转换
编辑动态 ( def
) 类型转换将原始 def
类型的值转换为任何目标类型的等效值,或者将任何原始类型的值转换为目标 def
类型的等效值。
始终允许从任何原始类型值到 def
类型值的隐式转换。始终允许从任何原始类型值到 def
类型值的显式转换,但永远没有必要。
当且仅当基于 def
类型值表示的当前类型值通常允许转换时,才允许从原始 def
类型值到任何目标类型值的隐式或显式转换。
示例
-
使用任何原始类型到目标
def
类型的有效动态类型转换。声明
def d0
;将int 3
隐式转换为def
;将int 3
存储到d0
分配
ArrayList
实例 →ArrayList 引用
;将ArrayList 引用
隐式转换为def
→def
;将def
存储到d0
声明
Object o
;分配HashMap
实例 →HashMap 引用
;将HashMap 引用
隐式转换为Object 引用
→Object 引用
;将Object 引用
存储到o
声明
def d1
;从o
加载 →Object 引用
;将Object 引用
隐式转换为def
→def
;将def
存储到d1
声明
int i
;从d1
加载 →def
;将def
隐式转换为HashMap 引用
→ HashMap 引用`; 对HashMap 引用
调用size
→int 0
;将int 0
存储到i
;(请注意,由于HashMap
是def
类型值表示的最底层的后代类型值,因此def
被隐式转换为HashMap 引用
) -
使用原始
def
类型到任何目标类型的有效动态类型转换。声明
def d
;将double 1.0
隐式转换为def
→def
;将def
存储到d
声明
int i
;从d
加载 →def
;将def
隐式转换为double 1.0
→double 1.0
;将double 1.0
显式转换为int 1
→int 1
;将int 1
存储到i
;(请注意,显式转换是必要的,因为double
类型值不会隐式转换为int
类型值)将
int 1
存储到d
;(请注意,d
代表的类型从double
切换到int
)声明
float i
;从d
加载 →def
;将def
隐式转换为int 1
→int 1
;将int 1
隐式转换为float 1.0
→float 1.0
;将float 1.0
存储到f
分配
ArrayList
实例 →ArrayList 引用
;将ArrayList 引用
存储到d
;(请注意,d
代表的类型从int
切换到ArrayList
)声明
List l
;从d
加载 →def
;将def
隐式转换为ArrayList 引用
→ArrayList 引用
;将ArrayList 引用
隐式转换为List 引用
→List 引用
;将List 引用
存储到l
-
导致错误的无效动态类型转换。
声明
def d
; 隐式转换int 1
为def
→def
; 将def
存储到d
声明
short s
; 从d
加载 →def
; 隐式转换def
为int 1
→int 1
; 错误 → 无法隐式转换int 1
为short 1
; (注意显式转换是有效的)分配
HashMap
实例 →HashMap 引用
; 隐式转换HashMap 引用
为def
→def
; 将def
存储到d
声明
List l
; 从d
加载 →def
; 隐式转换def
为HashMap 引用
; 错误 → 无法隐式转换HashMap 引用
为List 引用
; (注意,由于HashMap
和List
都不是对方的后代,因此没有转换是有效的)
字符串到字符的转换
编辑使用转换运算符将 String
类型的值转换为 char
类型的值。
错误
- 如果
String
类型的值的长度不是一个字符。 - 如果
String
类型的值是null
。
示例
-
将字符串字面量转换为
char
类型的值。 -
将
String
引用转换为char
类型的值。
装箱和拆箱
编辑装箱是一种特殊的转换类型,用于将原始类型转换为其对应的引用类型。拆箱是相反的操作,用于将引用类型转换为其对应的原始类型。
在以下操作期间会发生隐式装箱/拆箱
def
类型和原始类型之间的转换会根据需要隐式装箱/拆箱,尽管在整个文档中这被称为隐式转换。- 方法/函数调用参数会根据需要隐式装箱/拆箱。
- 当在原始类型值上调用引用类型方法时,原始类型值会被隐式装箱。
不允许显式装箱/拆箱。使用引用类型 API 显式地将原始类型值转换为其各自的引用类型值,反之亦然。
错误
- 如果进行了显式转换以装箱/拆箱原始类型。
示例
-
隐式装箱/拆箱的使用。
声明
List l
; 分配ArrayList
实例 →ArrayList 引用
; 将ArrayList 引用
存储到l
;从
l
加载 →List 引用
; 隐式转换int 1
为def
→def
; 使用参数 (def
) 调用List 引用
上的add
; (注意,在内部,int 1
被装箱为Integer 1
以存储为def
类型的值)声明
Integer I
; 使用 (int 0
) 的参数调用Integer
上的valueOf
→Integer 0
; 将Integer 0
存储到I
;声明
int i
; 从I
加载 →Integer 0
; 拆箱Integer 0
→int 0
; 从l
加载 →List 引用
; 使用参数 (int 0
) 调用List 引用
上的get
→def
; 隐式转换def
为int 1
→int 1
; 将int 1
存储到i
; (注意,在从def
类型的值加载时,内部将int 1
从Integer 1
中拆箱) -
导致错误的无效装箱/拆箱的使用。
提升
编辑提升是指当单个值隐式转换为特定类型,或者多个值隐式转换为相同类型时,某些操作需要进行计算。每个需要提升的操作都有一个提升表,该表显示了基于值类型的所有必需的隐式转换。在编译时提升为 def
类型的值在运行时会根据 def
值表示的类型再次提升。
错误
- 如果特定操作无法为给定值的类型找到允许的提升类型。
示例
-
提升的使用。
声明
double d
; 提升int 2
和double 2.0 @0
:结果double
; 隐式转换int 2
为double 2.0 @1
→double 2.0 @1
; 将double 2.0 @1
和double 2.0 @0
相加 →double 4.0
; 将double 4.0
存储到d
声明
def x
; 隐式转换int 1
为def
→def
; 将def
存储到x
;声明
float f
; 从x
加载 →def
; 隐式转换def
为int 1
→int 1
; 提升int 1
和float 2.0
:结果float
; 隐式转换int 1
为float 1.0
→float `1.0
; 将float 1.0
和float 2.0
相加 →float 3.0
; 将float 3.0
存储到f
; (注意,此示例说明了在运行时进行的提升,因为在编译时进行的提升会解析为def
类型的值)
允许的转换
编辑下表显示了所有允许的转换。逐行读取这些表,其中原始类型显示在第一列,随后的每一列指示转换为指定目标类型的转换是隐式 (I)、显式 (E)、仅用于方法的装箱/拆箱 (A)、引用类型转换 (@) 还是不允许 (-)。有关允许的引用类型转换,请参阅引用类型转换。
原始/引用类型
O |
N |
T |
b |
y |
s |
c |
i |
j |
f |
d |
B |
Y |
S |
C |
I |
J |
F |
D |
R |
def |
|
对象 ( O ) |
@ |
@ |
- |
- |
- |
- |
- |
- |
- |
- |
@ |
@ |
@ |
@ |
@ |
@ |
@ |
@ |
@ |
I |
|
数字 ( N ) |
I |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
@ |
@ |
- |
@ |
@ |
@ |
@ |
@ |
I |
|
字符串 ( T ) |
I |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
E |
- |
- |
- |
- |
- |
I |
|
布尔值 ( b ) |
A |
- |
- |
- |
- |
- |
- |
- |
- |
- |
A |
- |
- |
- |
- |
- |
- |
- |
- |
I |
|
字节 ( y ) |
A |
A |
- |
- |
I |
E |
I |
I |
I |
I |
- |
A |
A |
- |
A |
A |
A |
A |
- |
I |
|
短整型 ( s ) |
A |
A |
- |
- |
E |
E |
I |
I |
I |
I |
- |
- |
A |
- |
A |
A |
A |
A |
- |
I |
|
字符 ( c ) |
A |
- |
E |
- |
E |
E |
I |
I |
I |
I |
- |
- |
- |
A |
A |
A |
A |
A |
- |
I |
|
整型 ( i ) |
A |
A |
- |
- |
E |
E |
E |
I |
I |
I |
- |
- |
- |
- |
A |
A |
A |
A |
- |
I |
|
长整型 ( j ) |
A |
A |
- |
- |
E |
E |
E |
E |
I |
I |
- |
- |
- |
- |
- |
A |
A |
A |
- |
I |
|
单精度浮点型 ( f ) |
A |
A |
- |
- |
E |
E |
E |
E |
E |
I |
- |
- |
- |
- |
- |
- |
A |
A |
- |
I |
|
双精度浮点型 ( d ) |
A |
A |
- |
- |
E |
E |
E |
E |
E |
E |
- |
- |
- |
- |
- |
- |
- |
A |
- |
I |
|
布尔值 ( B ) |
A |
- |
- |
A |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
- |
@ |
I |
|
字节 ( Y ) |
A |
I |
- |
- |
A |
A |
- |
A |
A |
A |
A |
- |
A |
- |
A |
A |
A |
A |
@ |
I |
|
短整型 ( S ) |
A |
I |
- |
- |
- |
A |
- |
A |
A |
A |
A |
- |
- |
- |
A |
A |
A |
A |
@ |
I |
|
字符 ( C ) |
A |
- |
- |
- |
- |
- |
A |
A |
A |
A |
A |
- |
- |
- |
A |
A |
A |
A |
@ |
I |
|
整型 ( I ) |
A |
- |
- |
- |
- |
- |
- |
A |
A |
A |
A |
- |
- |
- |
- |
A |
A |
A |
@ |
I |
|
长整型 ( J ) |
A |
- |
- |
- |
- |
- |
- |
- |
A |
A |
A |
- |
- |
- |
- |
- |
A |
A |
@ |
I |
|
单精度浮点型 ( F ) |
A |
- |
- |
- |
- |
- |
- |
- |
- |
A |
A |
- |
- |
- |
- |
- |
- |
A |
@ |
I |
|
双精度浮点型 ( D ) |
A |
- |
- |
- |
- |
- |
- |
- |
- |
- |
A |
- |
- |
- |
- |
- |
- |
- |
@ |
I |
|
引用 ( R ) |
I |
@ |
@ |
- |
- |
- |
- |
- |
- |
- |
- |
@ |
@ |
@ |
@ |
@ |
@ |
@ |
@ |
@ |
I |
def
类型
O |
N |
T |
b |
y |
s |
c |
i |
j |
f |
d |
B |
Y |
S |
C |
I |
J |
F |
D |
R |
|
def 作为字符串 |
I |
- |
I |
- |
- |
- |
E |
- |
- |
- |
- |
- |
- |
- |
E |
- |
- |
- |
- |
@ |
def 作为布尔值/布尔值 |
I |
- |
- |
I |
- |
- |
- |
- |
- |
- |
- |
I |
- |
- |
- |
- |
- |
- |
- |
@ |
def 作为字节/字节 |
I |
- |
- |
- |
I |
I |
E |
I |
I |
I |
I |
- |
I |
I |
E |
I |
I |
I |
I |
@ |
def 作为短整型/短整型 |
I |
- |
- |
- |
E |
I |
E |
I |
I |
I |
I |
- |
E |
I |
E |
I |
I |
I |
I |
@ |
def 作为字符/字符 |
I |
- |
- |
- |
E |
E |
I |
I |
I |
I |
I |
- |
E |
E |
I |
I |
I |
I |
I |
@ |
def 作为整型/整型 |
I |
- |
- |
- |
E |
E |
E |
I |
I |
I |
I |
- |
E |
E |
E |
I |
I |
I |
I |
@ |
def 作为长整型/长整型 |
I |
- |
- |
- |
E |
E |
E |
E |
I |
I |
I |
- |
E |
E |
E |
E |
I |
I |
I |
@ |
def 作为单精度浮点型/单精度浮点型 |
I |
- |
- |
- |
E |
E |
E |
E |
E |
I |
I |
- |
E |
E |
E |
E |
E |
I |
I |
@ |
def 作为双精度浮点型/双精度浮点型 |
I |
- |
- |
- |
E |
E |
E |
E |
E |
E |
I |
- |
E |
E |
E |
E |
E |
E |
I |
@ |
def 作为引用 |
@ |
@ |
@ |
- |
- |
- |
- |
- |
- |
- |
- |
@ |
@ |
@ |
@ |
@ |
@ |
@ |
@ |
@ |