强制转换编辑

强制转换将原始类型的值转换为目标类型的等效值。隐式强制转换推断目标类型,并在某些操作期间自动发生。显式强制转换指定目标类型,并强制作为其自身操作发生。使用 强制转换运算符 '()' 来指定显式强制转换。

有关所有允许的强制转换的快速参考,请参阅强制转换表

错误

  • 如果在强制转换期间,目标类型不存在等效值。
  • 如果给出了隐式强制转换,但需要显式强制转换。

语法

cast: '(' TYPE ')' expression

示例

  • 有效的强制转换。

    int i = (int)5L;         
    Map m = new HashMap();   
    HashMap hm = (HashMap)m; 

    声明 int i; 显式强制转换 long 5int 5int 5; 将 int 5 存储到 i

    声明 Map m; 分配 HashMap 实例 → HashMap 引用; 隐式强制转换 HashMap 引用Map 引用Map 引用; 将 Map 引用 存储到 m

    声明 HashMap hm; 从 m 加载 → Map 引用; 显式强制转换 Map 引用HashMap 引用HashMap 引用; 将 HashMap 引用 存储到 hm

数值类型强制转换编辑

数值类型强制转换将原始数值类型的值转换为目标数值类型的等效值。两个数值类型值之间的强制转换会导致数据丢失,当原始数值类型的值大于目标数值类型可以容纳的值时。整数类型值和浮点类型值之间的强制转换会导致精度丢失。

下表以行的方式显示了每种数值类型的值的允许强制转换。

字节

短整型

字符

整型

长整型

浮点型

双精度型

字节

隐式

隐式

隐式

隐式

隐式

隐式

短整型

显式

显式

隐式

隐式

隐式

隐式

字符

显式

显式

隐式

隐式

隐式

隐式

整型

显式

显式

显式

隐式

隐式

隐式

长整型

显式

显式

显式

显式

隐式

隐式

浮点型

显式

显式

显式

显式

显式

隐式

双精度型

显式

显式

显式

显式

显式

显式

示例

  • 有效的数值类型强制转换。

    int a = 1;            
    long b = a;           
    short c = (short)b;   
    double e = (double)a; 

    声明 int a; 将 int 1 存储到 a

    声明 long b; 从 a 加载 → int 1; 隐式强制转换 int 1long 1long 1; 将 long 1 存储到 b

    声明 short c; 从 b 加载 → long 1; 显式强制转换 long 1short 1short 1; 将 short 1 值存储到 c

    声明 double e; 从 a 加载 → int 1; 显式强制转换 int 1double 1.0; 将 double 1.0 存储到 e; (注意,显式强制转换是多余的,因为隐式强制转换是有效的)

  • 导致错误的无效数值类型强制转换。

    int a = 1.0; // error 
    int b = 2;            
    byte c = b;  // error 

    声明 int i; 错误 → 无法隐式强制转换 double 1.0int 1; (注意,显式强制转换是有效的)

    声明 int b; 将 int 2 存储到 b

    声明字节 c; 从 b 加载 → int 2; 错误 → 无法隐式强制转换 int 2byte 2; (注意,显式强制转换是有效的)

引用类型强制转换编辑

引用类型强制转换将原始引用类型的值转换为目标引用类型的等效值。当原始引用类型是目标类型的后代时,允许两个引用类型值之间的隐式强制转换。当原始类型是目标类型的后代或目标类型是原始类型的后代时,允许两个引用类型值之间的显式强制转换。

示例

  • 有效的引用类型强制转换。

    List x;                        
    ArrayList y = new ArrayList(); 
    x = y;                         
    y = (ArrayList)x;              
    x = (List)y;                   

    声明 List x; 将默认值 null 存储到 x

    声明 ArrayList y; 分配 ArrayList 实例 → ArrayList 引用; 将 ArrayList 引用 存储到 y;

    y 加载 → ArrayList 引用; 隐式强制转换 ArrayList 引用List 引用List 引用; 将 List 引用 存储到 x; (注意,ArrayListList 的后代)

    x 加载 → List 引用; 显式强制转换 List 引用ArrayList 引用ArrayList 引用; 将 ArrayList 引用 存储到 y;

    y 加载 → ArrayList 引用; 显式强制转换 ArrayList 引用List 引用List 引用; 将 List 引用 存储到 x; (注意,显式强制转换是多余的,隐式强制转换是有效的)

  • 导致错误的无效引用类型强制转换。

    List x = new ArrayList();          
    ArrayList y = x;          // error 
    Map m = (Map)x;           // error 

    声明 List x; 分配 ArrayList 实例 → ArrayList 引用; 隐式强制转换 ArrayList 引用List 引用List 引用; 将 List 引用 存储到 x

    声明 ArrayList y; 从 x 加载 → List 引用; 错误 → 无法隐式强制转换 List 引用ArrayList 引用; (注意,显式强制转换是有效的,因为 ArrayListList 的后代)

    声明 ArrayList y; 从 x 加载 → List 引用; 错误 → 无法显式强制转换 List 引用Map 引用; (注意,没有强制转换是有效的,因为 ListMap 都不一个是另一个的后代)

动态类型强制转换编辑

动态 (def) 类型强制转换将原始 def 类型的值转换为任何目标类型的等效值,或将任何原始类型的值转换为目标 def 类型的等效值。

从任何原始类型值到 def 类型值的隐式强制转换始终是允许的。从任何原始类型值到 def 类型值的显式强制转换始终是允许的,但从不需要。

从原始 def 类型值到任何目标类型值的隐式或显式强制转换是允许的,当且仅当强制转换根据 def 类型值表示的当前类型值通常是允许的。

示例

  • 任何原始类型到目标 def 类型的有效动态类型强制转换。

    def d0 = 3;               
    d0 = new ArrayList();     
    Object o = new HashMap(); 
    def d1 = o;               
    int i = d1.size();        

    声明 def d0; 隐式强制转换 int 3def; 将 int 3 存储到 d0

    分配 ArrayList 实例 → ArrayList 引用; 隐式强制转换 ArrayList 引用defdef; 将 def 存储到 d0

    声明 Object o; 分配 HashMap 实例 → HashMap 引用; 隐式强制转换 HashMap 引用Object 引用Object 引用; 将 Object 引用 存储到 o

    声明 def d1; 从 o 加载 → Object 引用; 隐式强制转换 Object 引用defdef; 将 def 存储到 d1

    声明 int i; 从 d1 加载 → def; 隐式强制转换 defHashMap 引用 → HashMap 引用`; 在 HashMap 引用 上调用 sizeint 0; 将 int 0 存储到 i; (注意,def 隐式强制转换为 HashMap 引用,因为 HashMapdef 类型值表示的最子代类型值)

  • 原始 def 类型到任何目标类型的有效动态类型强制转换。

    def d = 1.0;         
    int i = (int)d;      
    d = 1;               
    float f = d;         
    d = new ArrayList(); 
    List l = d;          

    声明 def d; 隐式强制转换 double 1.0defdef; 将 def 存储到 d

    声明 int i; 从 d 加载 → def; 隐式强制转换 defdouble 1.0double 1.0; 显式强制转换 double 1.0int 1int 1; 将 int 1 存储到 i; (注意,显式强制转换是必要的,因为 double 类型值不会隐式转换为 int 类型值)

    int 1 存储到 d; (注意,d 表示的类型从 double 切换到 int

    声明 float i; 从 d 加载 → def; 隐式强制转换 defint 1int 1; 隐式强制转换 int 1float 1.0float 1.0; 将 float 1.0 存储到 f

    分配 ArrayList 实例 → ArrayList 引用;将 ArrayList 引用 存储到 d 中;(注意 d 代表的类型从 int 变为 ArrayList

    声明 List l;从 d 加载 → def;隐式转换 defArrayList 引用ArrayList 引用;隐式转换 ArrayList 引用List 引用List 引用;将 List 引用 存储到 l

  • 无效的动态类型转换导致错误。

    def d = 1;                  
    short s = d;       // error 
    d = new HashMap();          
    List l = d;        // error 

    声明 def d;隐式转换 int 1defdef;将 def 存储到 d

    声明 short s;从 d 加载 → def;隐式转换 defint 1int 1错误 → 无法隐式转换 int 1short 1;(注意显式转换是有效的)

    分配 HashMap 实例 → HashMap 引用;隐式转换 HashMap 引用defdef;将 def 存储到 d

    声明 List l;从 d 加载 → def;隐式转换 defHashMap 引用错误 → 无法隐式转换 HashMap 引用List 引用;(注意没有转换是有效的,因为 HashMapList 都不一个是另一个的子类)

字符串到字符转换编辑

使用转换运算符将 String 类型 值转换为 char 类型 值。

错误

  • 如果 String 类型的值不是一个字符长度。
  • 如果 String 类型的值为 null

示例

  • 将字符串字面量转换为 char 类型的值。

    char c = (char)"C"; 
    c = (char)'c';      

    声明 char c;显式转换 String "C"char Cchar C;将 char C 存储到 c

    显式转换 String 'c'char cchar c;将 char c 存储到 c

  • String 引用转换为 char 类型的值。

    String s = "s";   
    char c = (char)s; 

    声明 String s;将 String "s" 存储到 s 中;

    声明 char cs 加载 → String "s";显式转换 String "s"char schar s;将 char s 存储到 c

字符到字符串转换编辑

使用转换运算符将 char 类型 值转换为 String 类型 值。

示例

  • String 引用转换为 char 类型的值。

    char c = 65;          
    String s = (String)c; 

    声明 char c;将 char 65 存储到 c 中;

    声明 String sc 加载 → char A;显式转换 char AString "A"String "A";将 String "A" 存储到 s

装箱和拆箱编辑

装箱是一种特殊的转换,用于将基本类型转换为其对应的引用类型。拆箱是相反的操作,用于将引用类型转换为其对应的基本类型。

在以下操作中会发生隐式装箱/拆箱

  • def 类型和基本类型之间的转换会根据需要隐式装箱/拆箱,尽管在整个文档中这被称为隐式转换。
  • 方法/函数调用参数会根据需要隐式装箱/拆箱。
  • 当对基本类型值调用引用类型方法时,会隐式装箱基本类型值。

不允许显式装箱/拆箱。使用引用类型 API 显式地将基本类型值转换为其相应的引用类型值,反之亦然。

错误

  • 如果显式转换用于装箱/拆箱基本类型。

示例

  • 隐式装箱/拆箱的用法。

    List l = new ArrayList();       
    l.add(1);                       
    Integer I = Integer.valueOf(0); 
    int i = l.get(i);               

    声明 List l;分配 ArrayList 实例 → ArrayList 引用;将 ArrayList 引用 存储到 l 中;

    l 加载 → List 引用;隐式转换 int 1defdef;使用参数 (def) 对 List 引用 调用 add;(注意在内部 int 1 被装箱为 Integer 1 以便作为 def 类型值存储)

    声明 Integer I;使用参数 (int 0) 对 Integer 调用 valueOfInteger 0;将 Integer 0 存储到 I 中;

    声明 int i;从 I 加载 → Integer 0;拆箱 Integer 0int 0;从 l 加载 → List 引用;使用参数 (int 0) 对 List 引用 调用 getdef;隐式转换 defint 1int 1;将 int 1 存储到 i 中;(注意在内部 int 1Integer 1 拆箱,当从 def 类型值加载时)

  • 无效装箱/拆箱的用法导致错误。

    Integer x = 1;                   // error 
    Integer y = (Integer)1;          // error 
    int a = Integer.valueOf(1);      // error 
    int b = (int)Integer.valueOf(1); // error 

    声明 Integer x错误 → 在赋值期间无法隐式装箱 int 1Integer 1

    声明 Integer y错误 → 在赋值期间无法显式装箱 int 1Integer 1

    声明 int a;使用参数 (int 1) 对 Integer 调用 valueOfInteger 1错误 → 在赋值期间无法隐式拆箱 Integer 1int 1

    声明 int a;使用参数 (int 1) 对 Integer 调用 valueOfInteger 1错误 → 在赋值期间无法显式拆箱 Integer 1int 1

提升编辑

提升是指将单个值隐式转换为特定类型,或者将多个值隐式转换为相同类型,以便某些操作能够进行评估。每个需要提升的操作都有一个提升表,该表显示了根据值类型进行的所有必要的隐式转换。在编译时提升为 def 类型的值在运行时会根据 def 值所代表的类型再次提升。

错误

  • 如果特定操作无法为给定的值类型找到允许的提升类型。

示例

  • 提升的用法。

    double d = 2 + 2.0; 
    def x = 1;          
    float f = x + 2.0F; 

    声明 double d;提升 int 2double 2.0 @0:结果 double;隐式转换 int 2double 2.0 @1double 2.0 @1;将 double 2.0 @1double 2.0 @0 相加 → double 4.0;将 double 4.0 存储到 d

    声明 def x;隐式转换 int 1defdef;将 def 存储到 x 中;

    声明 float f;从 x 加载 → def;隐式转换 defint 1int 1;提升 int 1float 2.0:结果 float;隐式转换 int 1float 1.0float `1.0;将 float 1.0float 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 作为引用

@

@

@

-

-

-

-

-

-

-

-

@

@

@

@

@

@

@

@

@