基本类型的类型转换(隐式类型转换)和强制类型转换(译一)

smallclover

基本类型的类型转换和强制类型转换(一)

Java的变量类型分为2种。基本类型(原始类型)和引用类型。基本类型包括以下八种类型:boolean、 char、byte、short、int、long、float、double。引用类型包括一下三种类型,类(class)类型、接口(interface)类型、数组(Array)类型。

本章主要讲述基本类型之间转换的方法,转换包括由Java运行时环境隐式执行的类型转换和根据程序需要进行的强制类型转换。另外,关于引用类型的转换,请参照Class(引用类型的转换和强制类型转换)

目录

  • 基本类型的类型转换(隐式类型转换)
  • 基本类型的强制类型转换

基本类型的类型转换(隐式类型转换)

基本类型的类型转换是通过扩展转换的规则完成的。当Java运行时环境将数据的存储范围向更宽的类型转换的时,执行隐式类型转换。

类型转换规则

待转换的基本类型 可能的转换目标的基本类型
boolean 没有
char int, long, float, double
byte short, int, long, float, double
short int, long, float, double
int long, float, double
long float, double
float double
double 没有

以下将会说明Java运行时环境何时会进行隐式类型转换。

在赋值时进行类型转换

某个基本类型的变量,在赋值给其他基本类型的变量时,将会进行隐式的类型转换。转换遵循[类型转换规则]。

int x = 10;
double y;
y = x;
//变量x(int类型)赋值给变量y(double类型)时,将会执行隐式类型转换。int类型的变量转换为double类型之后,会执行赋值操作。因为它是按照[类型转换的规则]进行的,所以不需要程序员主动的进行转换。

int x = 10;
short y;
y = x;
//变量x(int类型)无法赋值给变量y(short类型)。因为int类型的变量x无法转换成shot类型的变量,short类型的存储范围小于int类型。执行的结果会出现编译错误。

在调用方法时的类型转换

在调用方法时,如果指定的类型与您要调用的方法的参数类型所需的类型不同,则会执行隐式类型转换。 在这种情况下,类型转换也遵循【类型转换规则】

short x = 10;
System.out.println(Integer.toString(x));

Integer.toString是一种将int类型数据转换为字符串的方法,该方法需要一个int类型的参数。 在如上所示代码,形参的类型为short类型的情况下 根据【类型转换规则】,short类型被转换为int类型之后,然后方法被执行,所以不会出现编译错误。

double y = 20.25;
System.out.println(Integer.toString(y));

double类型的变量被指定为参数时
由于不符合【类型转换规则】(double类型不能转换为int类型),执行结果为编译错误。

算术运算时候的类型转换

当使用算术运算符执行算术运算时,将执行隐式类型转换。 算术运算中的类型转换规则如下。

【算术运算符类型变换规则】

算术运算符 规则
单项运算符
(+, -, ~)
1. char, byte, short类型的变量会转化成int类型。
2. 除此之外不会进行转换。
二项运算符
(+, -, *, /, %, >>, >>>, <<, &, ^, 、竖线)
1. 其中一个变量为double类型的时候,另一个变量也会转换为double型。
2. 不含有double类型的变量的时候,其中一个变量为float类型,那么另一个变量也会变成float类型。
3. 不含有double、float类型的时候,其中一个变量为long类型,那么另一个变量也会变成long类型。
4. 不含有double、float、long类型的时候,其中一个变量为int类型,那么另一个变量也会变成int类型。

【例1】算术运算时进行转换的正确例子。

short x = 10;
double y = 20.25;
double z = -x + y;  //(1)
System.out.println(z);  //(2)

解释1

  • (1)变量x(short)类型,根据单项运算符(-)会转换为int类型。变量x(int类型)和变量y(double类型),根据二项运算符(+)会转换为double类型。然后赋值给变量z。
  • (2)运算结果10.25。

【例2】算术运算时进行转换编译错误的例子

short x = 10;
double y = 20.25;
int z = -x + y;  //(1)
System.out.println(z);

解释2

  • (1)变量x(short)类型,根据单项运算符(-)会转换为int类型。变量x(int类型)和变量y(double类型),根据二项运算符(+)会转换为double类型。。double类型的的运算结果无法赋值给z变量,编译错误。

一些解释说明(非原文)

也许有的读者会问,如何证明变量-x是int类型,苦于译者的水平,想不到如何用代码来证明,但是通过:

javap -c [class文件名]//java反汇编命令

也许可以一探究竟。

示例代码

public class HelloWorld {
    public static void main(String[] args) {
        short x = 10;
        double y = 20.25;
        double z = -x + y;
    }
}

使用javac命令编译后,运行javap -c命令进行反编译,编译结果如下

Compiled from "HelloWorld.java"
public class HelloWorld {
  public HelloWorld();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return

  public static void main(java.lang.String[]);
    Code:
       0: bipush        10
       2: istore_1
       3: ldc2_w        #2                  // double 20.25d
       6: dstore_2
       7: iload_1
       8: ineg
       9: i2d
      10: dload_2
      11: dadd
      12: dstore        4
      14: return
}

第0行:使用bipush将10推入栈顶时,会被扩展为32bit int类型的值。
第3行:使用ldc2_将将long或double型常量值从常量池中推送至栈顶(宽索引),这里常量是10
第7行:使用iload_1将第2个int类型的局部变量入栈,也就是10。
第8行:使用ineg将栈顶int型数值取负,并且结果进栈。
第9行:使用i2d将栈顶int值强转double值,并且结果进栈。
第10行:使用dload_2将第3个double类型的局部变量入栈,也就是20.25d。
第11行:使用dadd将栈顶两double型数值相加,并且结果进栈。
第12行:使用dstore将栈顶double类型的值存入指定的局部变量。

_(:з」∠)_,好像解释的并不怎么好。要是有好的办法,希望能告诉我,大家一起学习。谢谢。

---未完待续---

阅读 3.4k

目前,刚入职在日本东京都一家企业工作中。

173 声望
10 粉丝
0 条评论

目前,刚入职在日本东京都一家企业工作中。

173 声望
10 粉丝
文章目录
宣传栏