java 基本数据类型
类型转换:
基本数据类型(boolean除外)之间可以互相转换。
引用类型转换的前提是存在继承或实现关系。
在强转之前,建议先使用instanceof 关键字判断。接口引用也可以利用instanceof关键字判断是否是子类的一个实例。
Integer 和 Long 之间没有继承和实现的关系,所以不能强转。
Long i = (Long)new Integer(100); // Cannot cast from Integer to Long
或者
Integer i = 100;
Object obj = (Long)i; // Cannot cast from Integer to Long
1、java 基本数据类型四类八种:
byte、short、int、long、float、double、char、boolean
2、类型转换
八种基本类型boolean 除外,其它七种都可以互相转换。
自动转换,小类型转大类型。
强转,大类型转小类型。
例外(不需要强转):为了方便起见,int类型字面直接量可以直接赋值给byte、short、char,只是不能超出范围,如:
public class Test { byte b = 50; byte b1 = 100+1;//java编译器会自动运算为101,所以视为直接量 byte b2 = b+1; //这个不是直接量,报错 byte b3 = 255; //超出范围了,报错 }
超出范围的强转会丢失精度,因为不同类型所占字节不同,大类型转小类型会果断地把高位砍掉,如:
public class Test { public static void main(String[] args) { byte b = 67; byte b2 = 89; byte b3 = (byte) (b + b2); // int值156的内存表示: // 0000 0000 0000 0000 0000 0000 1001 1100 // 砍掉高24位 1001 1100 // 计算器输入十进制-100,转为二进制正好为 1001 1100 System.out.println(b3);// 输出为-100 } }
public class Test { public static void main(String[] args) { long l = 2147483648L*2+12345;//4294979641 /* * 4294979641的二进制表示为(64位): * 00000000000000000000000000000001 * 00000000000000000011000000111001 * 砍掉高32位: * 00000000000000000011000000111001 * 对应的数十进制数为:12345 */ int i = (int) l; System.out.println(i);//i=12345 } }
正常情况下,double 也可以强转为float ; 但如果超出范围,强转不过来,因为有一个小数点,如果也随便地砍掉,格式就不对了。不过即使这样也没有语法错误,运行时也没有错误,只是结果不是我们想要的结果,结果为Infinity。
public class Test { public static void main(String[] args) { // float f1 = 1.1;// 报错 float f2 = (float) 1.1; float f3 = (float) (1.1 * 10E300);// 不报错,但结果为无穷大 // float f5 = 1.0*10E39L;// 报错 float f6 = (float)(1.0*10E39);//结果为无穷大 System.out.println(f2); System.out.println(f3); System.out.println(f6); } }
3、运算
小类型和大类型运算时,小类型自动转为大类型。
byte、short、char 参加运算时,首先转换为int 型,如:
public static void main(String[] args) { byte b = 1; byte b1 = 2; byte b2 = (byte)(b + b1); int i = b + b1; }
如果运行的结果超出了表示范围,那么就会溢出,溢出不会报错。
public static void main(String[] args) { byte b1 = 127; byte b2 = 1; byte b3 = (byte)(b1+b2); System.out.println(b3);//输出-128 }
4、也可以把八进制(以0打头)、十六进制(以0x或0X打头)数赋值给byte、short、int、long、float、double、char。
public class Test { public static void main(String[] args) { byte b = -100, b2 = -0100, b3 = -0X10; short s = 100, s2 = 0100, s3 = 0x10; int i = 100, i2 = 0100, i3 = 0x10; long l = 100, l2 = 0100, l3 = 0x10; float f = 100, f2 = 0100, f3 = 0x10; double d = 100, d2 = 0100, d3 = 0x10; char c = 100, c1 = 0100, c3 = 0x10; } }
但十六进制的不能赋值为浮点数类型:
public class Test { public static void main(String[] args) { double d = 100.1, d2 = 0100.1;//这一行正常 double d3 = 0x10.1;//这一行报错 } }
也可以使用十六进制的另外一种形式赋值给它们,但一定要在char 所表示的范围内。
public class Test { public static void main(String[] args) { byte b = '\u0001'; short s = '\u1111'; int i = '\udddd'; int i2 ='\u11111';//报错,因为这里有5位,对应20位二进制数。 long l = '\uffff'; char c = '\uffff'; float f = '\uffff'; double d = '\uffff'; double d2 ='\uffffff';//报错,因为这里有5位,对应20位二进制数。 //20位二进制的数超出了char的表示范围,char是16位的。 System.out.println("b="+b+",s="+s+",i="+i+",l="+l+",c="+c+",f="+f+",d="+d); } }
5、char 类型
java 为了实现跨平台,使用Unicode 编码,Unicode 又分为2 种,UTF-8 和UTF-16。
java 采用的是UTF-16 编码方式,所以一个字符在内存中占用两个字节,比如‘a’ 这个字符在内存中也占用两个字节。
char 类型的声明:
char c1 = '中';
char c2 = 97;
char c3 = '\u0061';
97和 0061分别是十进制和十六进制的,各自都有对应的二进制形式,即它们在内存中的存储形式,一个二进制数对应Unicode 字符集中的一个确定的字符。
97默认是int 类型的,对应的二进制数为0000 0000 0000 0000 0000 0000 0110 0001,一共四个字节,32位;类型转换,砍掉高位的两个字节变为两个字节,16位:0000 0000 0110 0001,这个二进制数会对应Unicode 字符集里的一个字符。
6、浮点型数据
单精度浮点型、双精度浮点型
声明为十进制形式的:float f = 3.14
声明为科学记数法形式的:float f = 3.14e10F, f2 = 3.14E10f, f3 = 3.14E-10F;
0——1之间有无数个浮点数,所以浮点数是有误差的。在第几位出现误差叫做精度。float 7位,double 15位。
0.1内部用0.0999很多个9来模拟。
计算机里的浮点数是离散的,现实中的浮点数是连续的、无穷的。