数据类型 | 字节数 | 二进制位数 | 范围 | 缓存值 |
---|---|---|---|---|
byte | 1 | 8 | -128~127 | -128~127 |
short | 2 | 16 | -32768~32767 | -128~127 |
int | 4 | 32 | -2147483648~2147483647 | -128~127 |
long | 8 | 64 | -9223372036854775808 ~ 9223372036854775807 | -128~127 |
float | 4 | 32 | 1.4E-45~3.4028235E38 | 无 |
double | 8 | 64 | 4.9E-324~1.7976931348623157E308 | 无 |
char | 2 | 16 | 0~65535 | 0~127 |
boolean | 1 | 8 | true/false | true/false |
使用注意
long型后如果不加L则默认为int型,浮点型如果不加F则默认为double型。
自动拆装箱与缓存机制
Integer a = 0;
Integer a = Integer.valueOf(0); //手动装箱
int b = a;
int b = a.intValue();//手动拆箱
Boolean的缓存是true,false,Byte、Short、Integer、Long的缓存都是-128到127。Character是缓存是0~127对应的字符。
在执行Integer a = new Integer(0)时,JVM会先创建一个对象,值为0,再把这个对象的引用赋值给a。基于节约内存和效率等的考虑,Java对包装类的values方法做了一些优化。如Integer,在执行Integer a = Integer.values(0)时,Java会在缓存中直接找到之前创建好的缓存,直接把0相应的引用给a。
Integer a1 = 0;//Integer a = Integer.value(0)
Integer b1 = 0;
Integer c1 = new Integer(0);
Integer a2 = 128;
Integer b2 = 128;
Integer c2 = new Integer(128);
System.out.println(a1 == b1); //true(缓存范围是-128~127)
System.out.println(a1 == c1); //false
System.out.println(a2 == b2); //false
System.out.println(a2 == c2); //false
这里Integer和int类型进行"=="比较,会把Integer类型自动拆箱进行比较。
long a = 1L;
int b = 1;
short c = 1;
System.out.println(a == b); //true
System.out.println(a == c); //true
使用原则
最后我们来整理一下基本类和包装类在实际使用时,应该遵循哪些原则?
1.尽量使用values方法。最大可能使用缓存,提高程序的效率。
2.类变量使用包装类。想象有一个和数据库表对应的实体类,如果你使用的基本数据类型,在插入时,可能会插入一些让你意想不到的初始值。
3.方法的参数要使用包装类。使用包装类意味着你在调用时,可以令若干个参数为null。null是无意义的。但是如果你使用了基本数据类型,那么,你将不得不传入一个值,即使这个值对你来说,没有什么意义。
4.方法的返回值要根据是否可为null来确定使用包装类还是基本类。当一个方法的返回值,一定不会出现null的情况时,推荐使用基本类来作为返回值。这样,调用者在拿到这个方法的返回值时,就不必担心它是为null了。
5.方法内部(局部变量)使用基本类型。基本类型的时间效率和效率上来说,都是要优于包装类的。所以,在方法内部,能使用基本类型尽量不要使用包装类。
6.小数的计算。严格来说,这条不属于基本类型和包装类的内容,但是,这里顺便提交,当涉及到小数的计算时,要考虑到计算的精度问题,可以使用BigDecimal,也可以通过缩小计量单位,达到化零为整的目的,这个,根据具体场景来确定。
彩蛋
如果定义int类型的i为int的最大值,那么i + 1会怎么样呢?
int i = Integer.MAX_VALUE;
System.out.println(i);
System.out.println(i + 1);
网友评论