Java中有一部分类型不使用new来创建对象,而是创建一个并非是“引用”的变量,它们直接储存值。这样的类型被称为基本类型,置于堆栈中。1
1. 基本类型
1.1 表格
1.2 注意事项
- Java中基本类型所占的存储空间是固定的,不随机器硬件的变化而变化,这也是Java可移植性更高的原因之一。
- boolean类型所占的存储空间没有明确指定,只有两个字面值:true/false。
- 所有的数值类型(上表前六项)都有正负号,没有无符号的数值类型。
1.3 字面值
- 对于整型来说,通过在数值前加上“0x”/“0X”来表示十六进制数,如:0xB34F;加上“0”来表示八进制数,如0777,此时如果写成0778就会出现报错,可见确实是八进制数;加上“0b”/“0B”来表示二进制数,如0b101;
- 对于浮点型,当数值仅为整数时,可以用相同方法来表示二、八、十六进制,比如
double d1 = 0xF12B;
当数值有小数时,不能直接表示,需要使用特殊的科学计数法:
double d1 = 0X1.BP2;//P2表示乘以2的2次方
- 整数字面值的默认类型是int,浮点数字面值的默认类型是double。
byte b = 127;
/*如果输入byte b = 128;则代码会报错,因为字面值128默认为int类型,超出byte类型最大值127
无法直接进行int类型到byte类型的类型转换。
需要进行强制转换:
*/
byte b = (byte)128;//此时不会报错,但事实上b的值也不为128,因为128超出byte表示范围。
- 表示单精度浮点数float时,可在末尾加上F/f,表示long时,可在末尾加上L/l。
/*long l = 2147483648;该表达式会报错。原因是这个数的字面值为int,但是数值却超过了int类型的最大值
编译器会提示超出int类型的范围*/
//要想将字面值表示为long类型,就要加上后缀L/l:
long l = 2147483648L;
2. 包装器类型
通过包装器类,我们可以在堆中创建一个非基本类型的对象,用来表示基本类型,例如:
//使用包装器类型Character的对象ch/ch_来表示对应的基本类型char:
Character ch = new Character('x');//这个构造器已经不推荐使用,这里用于演示
Character ch_ = Character.valueOf('x');//推荐使用valueOf方法来获得一个指定值的Character实例
Java SE5后提供的自动包装功能可以自动地将包装器类型和基本类型进行相互转换:
//自动包装功能:
Character a = 'x';//将基本类型转换为包装器类型
char b = a;//将包装器类型转换为基本类型
3. 类型转换
每个表达式都有类型,当前后类型不匹配时,就会进行隐式的类型转换或者造成编译错误。
3.1 扩展转换
由表示数据范围小的转换成表示数据范围大的:
扩展转换不会丢失信息,比较安全。但是从整型转换为浮点型时,可能会损失精度。上图虚线部分表示可能会损失精度的转换。例如将int类型的最大值转换为float类型:
float f = Integer.MAX_VALUE;
System.out.println("int类型:"+Integer.MAX_VALUE);
System.out.println("float类型:"+f);
得到如下结果:
可以发现float类型的结果不如int原值精确,即损失了精度。
3.2 窄化转换
由表示数据范围大的转换成表示数据范围小的。
按上图的箭头反方向即为窄化转换。
窄化转换很可能会丢失信息,是危险的,并且不能隐式进行,必须要显式转换。进行显式转换时,利用(type)后面接上你需要进行转换的变量,如(int)a可将变量a转换为int类型的。
3.3 截尾与舍入
double above = 0.7, below = 0.4;
float fabove = 0.7f,fbelow = 0.4f;
System.out.println("int类型的above:"+(int)above);
System.out.println("int类型的below:"+(int)below);
System.out.println("int类型的fabove:"+(int)fabove);
System.out.println("int类型的fbelow:"+(int)fbelow);
结果如下:
可以看到,原本的小数在转换后变成了0,信息丢失了,而且不论小数大于0.5还是小于0.5,都变为0,因此我们可以知道,Java在将整型转换为float或者double时,总是对该数字进行截尾,如果要得到四舍五入的结果,必须使用java.lang.Math中的round()方法。
3.4 提升
/*以下代码会报错
byte by1 = 1,by2 = 2,by3 ;
by3 = by1 + by2;
*/
//以下代码是正确的:
byte by1 = 1,by2 = 2,by3 ;
by3 = (byte) (by1 + by2);
这里表明了一点:只要类型比int小(char,byte,short),那么在运算之前,这些值会自动转换成int,所以最终的结果就会是int型的,因此需要进行类型转换。
通常,表达式中出现的最大的数据类型决定了表达式最终结果的数据类型。例如float乘double,结果就是double;int加long,结果就是long。
3.5 布尔型与“类”
boolean类型不能进行任何类型转换的处理,事实上能对boolean值进行的运算也非常有限。
对“类”进行类型转换需要特殊方法,同时也是有限制的。
文章内容参考自《Java编程思想》,我的老师的课件,网络以及自己的思考,主要作为自己整理的笔记使用。理解上表达上可能存在错误,欢迎指正。 ↩︎