解密Java中的类型转换问题

众所周知Java中的数据类型是强数据类型,基本数据类型之间的转换尤其固定的规则,当数据宽度比较窄的数据类型(如int)转换成数据类型比较宽的数据类型时(如double),则窄的数据类型会加宽,可以完成自动类型转换,这称为隐式转换。

如:以下代码没有任何问题,结果也是正确的,成绩不会发生变化,所不同的是成绩的精度提高了。

intintScore = 96;
doubledoubleScore = intScore;

那么如果试图把宽的数据类型(如double)转换成窄的数据类型(如float)时,编译器会提示编译错误,想要编译通过,需要进行强制类型转换。那么,此时的数据会发生截断。产生的结果是:

1. 数据正确,只是精度降低了;

2. 数据不正确,发生了溢出;

对于上述第1种情况,比较好理解,我们来看个例子:

float floatWeight= 63.5; //编译错误
double doubleWeight= 63.5;

上述第一条语句会提示编译错误,那是因为编译器看到63.5时,会把它当做一个double类型,把一个double类型赋给float类型,当然编译不通过了。推荐的解决方案是:

float floatWeight = 63.5f;

当然,你也可以强制转换成float类型:

float floatWeight = (float)63.5;

其实,上述语句本质是把double类型的数据强制转换成float类型,发生了截断。虽然数据的大小没有变化,但是数据的精度却降低了。

同理:

doubleWeight = floatWeight; //隐式转换
floatWeight = (float)doubleWeight;//强制转换

现在,问题来了,既然是截断,怎么会产生溢出呢?我们先来看个例子:

shorti = 150;
shortj = 75;
byteb = (byte) i; 
byted = (byte) j; 
System.out.println("b = " + b);
System.out.println("d = " + d);

以上代码的输出结果是:

b = -106

d = 75

看到结果,不免会问为什么b=-106呢?这是因为强制转换时发生溢出。由于150超出了byte能够表示的最大范围(-128 ~ 127)。

那么-106又是如何得来的呢?

i = 150,用二进制表示i = 0000 0000 1001 0110,short类型占2个字节,16位,最高位的0表示正数。当把i强制转换成byte类型时,高位发生截断,i = 1001 0110。在计算机中,用补码表示,最高位的1表示负数,那么用原码表示的话:i = 1110 1010,正好表示十进制数-106。

至此,也就解释了为什么截断也可能会发生溢出。

时间: 2024-08-08 13:43:55

解密Java中的类型转换问题的相关文章

java中强制类型转换

在Java中强制类型转换分为基本数据类型和引用数据类型两种,这里我们讨论的后者,也就是引用数据类型的强制类型转换. 在Java中由于继承和向上转型,子类可以非常自然地转换成父类,但是父类转换成子类则需要强制转换.因为子类拥有比父类更多的属性.更强的功能,所以父类转换为子类需要强制.那么,是不是只要是父类转换为子类就会成功呢?其实不然,他们之间的强制类型转换是有条件的. 当我们用一个类型的构造器构造出一个对象时,这个对象的类型就已经确定的,也就说它的本质是不会再发生变化了.在Java中我们可以通过

Java中数据类型转换

1.Java的数据类型分为三大类 布尔型,字符型和数值型 其中数值型又分为整型和浮点型 2.Java的变量类型 布尔型 boolean 字符型 char 整型    byte,short,int,long 浮点型 float,double 3.数据类型转换 Java中数据类型转换分为三种,简单数据类型转换,字符串与其他类型转换,其他实用数据类型转换 (1)简单数据类型转换 在Java中,整型,实型,字符型被视为简单数据类型. 这些类型级别从低到高:(byte,short,char)-> int

c#中的里氏转换和Java中强制类型转换在多态中的应用

在c#中: 注意: 子类并没有继承父类的构造函数,而是会默认调用父类那个无参数的构造函数. 如果一个子类继承了一个父类,那么这个子类除了可以使用自己的成员外,还可以使用从父类那里继承过来的成员.但是父类永远都只能使用自己的成员,而不能使用子类的成员. 子类之间也不能互相使用对方的成员. 里氏转换的概念: 1).子类可以赋值给父类 2).如果父类中装的是子类对象,那么可以讲这个父类强转为子类对象. namespace 里氏转换_接口练习 { class Program { static void

Java中数据类型转换问题

boolean类型不可以转换为替他的数据类型. Java中byte(8位).short(16位).char三种类型的优先级是相同的,相同优先级之间是不能进行自动转换的(如果相互转换的话,必须强制类型转换),只能将低类型自动转换为高类型,例如,可以将byte自动转换为int类型.(char 在java中是2个字节.java采用unicode,2个字节(16位)来表示一个字符. 再将char类型的数据赋给高优先级类型时,这时会自动类型转换,并且将该char的unicode编码赋给高优先级类型的变量)

JAVA中的类型转换

JAVA中类型转换的基本原则在于,(布尔型除外,无法转换)低精确度或者说小范围的类型可以自动地转为高精度或者大范围的类型,反之则需要强制转换.如图所示,左边的类型可以自动转换为右边的类型(一般发生在与大范围的类型的运算中),反之则需要强制转换. 图片来源(http://www.cnblogs.com/lwbqqyumidi/p/3700164.html) 如下题LeetCode 400. Nth Digit中,第七行会报错,可以看到count是long,len是int,两数相乘时len会自动变为

Java基础知识强化22:Java中数据类型转换

数据类型转换: (1). 自动转换 低级变量可以直接转换为高级变量,这叫自动类型转换.比如: byte b: int b:  long b:  float b:   double  b: 上面的语句可以在Java中直接通过. (2).如果低级类型为char型,向高级类型(整型)转换时候,会转换为对应的ASCII码值,例如: char c ='c':  int i = c:  System.out.println("output:"+i): 输出: output:99 (3).对于byt

Java基础---Java中自动类型转换(七)

Java中的自动类型转换 在 Java 程序中,不同的基本数据类型的数据之间经常需要进行相互转换.例如: , 代码中 int 型变量 score1 可以直接为 double 型变量 score2 完成赋值操作,运行结果为: 这种转换称为自动类型转换. 当然自动类型转换是需要满足特定的条件的: 1.  目标类型能与源类型兼容,如 double 型兼容 int 型,但是 char 型不能兼容 int 型 2.  目标类型大于源类型,如 double 类型长度为 8 字节, int 类型为 4 字节,

Java基础---java中强制类型转换(八)

Java中的强制类型转换 相信小伙伴们也发现了,尽管自动类型转换是很方便的,但并不能满足所有的编程需要. 例如,当程序中需要将 double 型变量的值赋给一个 int 型变量,该如何实现呢? 显然,这种转换是不会自动进行的!因为 int 型的存储范围比 double 型的小.此时就需要通过强制类型转换来实现了. 语法:( 数据类型 ) 数值 运行结果:  可以看到,通过强制类型转换将 75.8 赋值给 int 型变量后,结果为 75,数值上并未进行四舍五入,而是直接将小数位截断. 明白了吧,强

Java中数据类型转换大全(个人总结)

一.字符串转换为其他类型 1.将字符串转化为int型 (1)方法一 int i = Integer.parseInt(String str); (2)方法二 int i = Integer.valueOf(String str).intValue(); 注:Integer.parseInt和 Integer.valueOf 不同,前者生成的是整型,而后者是一个对象,所以要通过intValue()来获得对象的值: 字串转成 Double, Float, Long 的方法大同小异. 2.将字符串转化