1. Java数据类型
在Java中,数据类型可以分为两大种,Primitive Type(基本类型)和Reference Type(引用类型)。
基本类型的数值不是对象,不能调用对象的toString()、hashCode()、getClass()、equals()等方法,所以Java提供了针对每种基本类型的包装类型。如下:
INDEX |
基本类型 |
大小 |
数值范围 |
默认值 |
包装类型 |
1 |
boolean |
--- |
true,false |
false |
Boolean |
2 |
byte |
8bit |
-2^7-- 2^7-1 |
0 |
Byte |
3 |
char |
16bit |
\u0000 - \uffff |
\u0000 |
Character |
4 |
short |
16bit |
-2^15 -- 2^15-1 |
0 |
Short |
5 |
int |
32bit |
-2^31 -- 2^31-1 |
0 |
Integer |
6 |
long |
64bit |
-2^63 -- 2^63-1 |
0 |
Long |
7 |
float |
32bit |
IEEE 754 |
0.0f |
Float |
8 |
double |
64bit |
IEEE754 |
0.0d |
Double |
9 |
void |
--- |
--- |
--- |
Void |
2. Java自动装箱和拆箱的定义
1. 自动装箱:把基本类型用它们对应的引用类型包装起来,使它们具有对象的特质,可以调用toString()、hashCode()、getClass()、equals()等方法。如:
Integer a = 3; //自动装箱
编译器内部会调用static Integer valueOf(int i)这个 方法,valueOf(int i)返回一个指定int值的Integer对象,那么就变成这样
Integer a = 3; ---> Integer a = Integer.valueOf(3);
2. 拆箱:跟自动装箱的方向相反,将Integer及Double这样的引用类型的对象重新简化为基本类型的数据。如:
int i = new Integer(2);//这是拆箱
编译器内部会调用int intValue()返回该Integer对象的int值
Note:自动装箱和拆箱由编译器完成,编译器会在编译器根据语法决定是否进行装箱和拆箱操作。
3. 装箱和拆箱是如何实现的
我们就以Interger类为例,下面看一段代码:
1. package BoxingAndUnboxing; 2. 3. public class BoxingAndUnboxing { 4. public static void main(String[] args){ 5. 6. Integer i = 10; 7. int n = i; 8. } 9. }
反编译class文件之后得到如下内容:
1. public class BoxingAndUnboxing.BoxingAndUnboxing { 2. public BoxingAndUnboxing.BoxingAndUnboxing(); 3. Code: 4. 0: aload_0 5. 1: invokespecial #1 // Method java/lang/Object."<init>":()V 6. 4: return 7. 8. public static void main(java.lang.String[]); 9. Code: 10. 0: bipush 10 11. 2: invokestatic #7 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer; 12. 5: astore_1 13. 6: aload_1 14. 7: invokevirtual #13 // Method java/lang/Integer.intValue:()I 15. 10: istore_2 16. 11: return 17. }
从反编译得到的字节码内容可以看出,在装箱的时候自动调用的是Integer的valueOf(int)方法。而在拆箱的时候自动调用的是Integer的intValue方法。
其他的也类似,比如Double、Character,不相信的朋友可以自己手动尝试一下。
因此可以用一句话总结装箱和拆箱的实现过程:
装箱过程是通过调用包装器的valueOf方法实现的,而拆箱过程是通过调用包装器的 xxxValue方法实现的。(xxx代表对应的基本数据类型)。
4. 面试题常见坑
思考下面的代码输出什么
1. public static void main(String[] args) { 2. //1 3. Integer a=new Integer(123); 4. Integer b=new Integer(123); 5. System.out.println(a==b);//输出 false 6. 7. //2 8. Integer c=123; 9. Integer d=123; 10. System.out.println(c==d);//输出 true 11. 12. //3 13. Integer e=129; 14. Integer f=129; 15. System.out.println(e==f);//输出 false 16. //4 17. int g=59; 18. Integer h=new Integer(59); 19. System.out.println(g==h);//输出 true 20. }
常量池模型如下:
参考链接:
https://blog.csdn.net/u013309870/article/details/70229983