Java中自动类型转换溢出问题引发的探究 |
您所在的位置:网站首页 › 整型数据溢出的程序实例 › Java中自动类型转换溢出问题引发的探究 |
文章目录
语言类型的强弱并没有好坏之分Java中所有的数值类型所占据的字节数量与平台无关数据类型之间的转换数据溢出问题整型类型溢出整型转换为字符型的溢出
语言类型的强弱并没有好坏之分
编程鼻祖C语言是有类型的语言,在C语言中的变量必须满足:“在使用前定义,并确定类型”。在C语言之后的编程语言向着两个方向发展: C++、Java为代表的强类型语言 更加强调类型,对类型的检查比C语言更严格。JavaScript、Python、PHP为代表的弱类型语言 不看重类型,甚至不需要事先定义。一般来说,面向底层的语言更加强调类型;而越是面向应用的语言会越忽视类型,而去重视事务逻辑的处理。 Java中所有的数值类型所占据的字节数量与平台无关C/C++中int和long等类型的大小与目标平台相关,因为程序需要针对不同的处理器选择最为高效的整型,例如,在32位处理器上long值为4字节;在64位处理器上则为8字节。这样就有可能造成一个在64位处理器上运行的很好的C程序在32位处理器上运行却发生整数溢出。这就为编写跨平台程序带来了很大的难度。 而在Java中,所有的数值类型所占据的字节数量与平台无关,即数值类型的范围与运行Java代码的机器无关,这也是Java跨平台的一个表现。 另外,Java中的int、long、short、byte类型都是有符号的。底层的二进制形式中,首位如果是 0,就是正的;首位是1就是负的。另外,char则是0-65535的无符号数,从char转换到int类型时,缺少的高16位字节用0扩展。 Java - Type默认值大小取值范围byte01字节-128 - 127short02字节-32768 - 32767int04字节-2147483648 to 2147483647(21亿多)long0L8字节-232-1 to (232-1-1)float0.0f4字节±1.4E-45 to ±3.4028235E+38(有效位数为6~7位)double0.0d8字节±4.9E-324 to ±1.7976931348623157E+308(有效位数为15位)char‘\u0000’2字节0-65535booleanfalse取决于Java虚拟机true 或 false
特别的:整型向字符型转换时,JVM会把数字当成字符的ASCII编码来处理。 //将整型类型强制转换为字符型时,JVM会把数字当成字符的ASCII编码来处理. char i = (char)97; System.out.println(i);//输出:a 数据溢出问题数据溢出问题就是:当某一种类型的数值已经达到了此类型能够保存的最大值之后,再继续扩大,或者达到了最小值后再继续缩小,就会出现数据溢出问题。 整型类型溢出下面的代码以int类型为例,测试对int类型进行溢出测试: package com.gql; /** int类型的溢出测试 @author Hudie @date 2020/10/2 - 11:53 */ public class Test { public static void main(String[] args) { //int类型的最小值为:-2^31 int a = -2147483648; System.out.println("int类型的最小值为:"+a); System.out.println("int类型的最小值减1为:"+(a-1)); System.out.println("int类型的最小值减2为:"+(a-2)); System.out.println("int类型的最小值减3为:"+(a-3)); System.out.println("int类型的最小值减4为:"+(a-4)); System.out.println("//总结:超过最小值的数据会向下溢出变成正数.\n"); //int类型的最大值为2^31 - 1 a = 2147483647; System.out.println("int类型的最大值为:"+a); System.out.println("int类型的最大值加1为:"+(a+1)); System.out.println("int类型的最大值加2为:"+(a+2)); System.out.println("int类型的最大值加3为:"+(a+3)); System.out.println("int类型的最大值加4为:"+(a+4)); System.out.println("总结:超过最大值的数据会向上溢出变成负数.\n"); } }上面的代码符合了整型的数据溢出规则:即超过最大值的整型数值会向上溢出变成负数;超过最小值的整型数值会向下溢出变成正数。 前文提到过,Java中的int、long、short、byte类型都是有符号的。而在C/C++语言中,溢出规则分为两种: 有符号的整型溢出:“undefined behavior”,即由编译器实现,通常的编译器都是按照上面测试的整型数据溢出规则。无符号的整型溢出:溢出后的数会以2^(8*sizeof(type))作模运算 整型转换为字符型的溢出字符型数据在内存中一般情况下下占据一个字节(如今有些Unicode字符需要用两个char来描述),其存放的就是这个字符对应的ASCLL码的整数值,所以字符型数据和整型数据之间可以通用。
下面的代码演示整型向字符型转换时出现的溢出情况。 int j = (char)0; System.out.println(j); j = (char)-1; System.out.println(j); j = (char)-2; System.out.println(j); j = (char)-3; System.out.println(j); System.out.println("总结:超过最小值的数据会向下溢出变成正数"); System.out.println("-------"); j = (char)65535; System.out.println(j); j = (char)65536; System.out.println(j); j = (char)65537; System.out.println(j); System.out.println("总结:超过最大值的数据会向下溢出仍变成正数(因为char类型的符号位永远是0,即正数)");可以发现整型转换为字符型时的溢出规律: 当超过最小值的数据时会向下溢出,变成正数,所以直接取了char类型的最大值65535。当超过最大值的数据时会向上溢出,由于字符型不能变成负数,所以直接取了最小值0。可以将上面两条概括理解为,超过最大值后,取最小值;超过最小值后,取最大值。 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |