坑介绍,具体请先看代码
public void test1(){
Integer a = null;
int b = 6;
if(b > a){
System.out.println("a>b");
}
}
上面的代码编译没有什么问题,但是运行就报错空指针,具体原因就是自动拆箱引起的,
代码分析
定义a和b,在if中做判断的时候,因为b是int类型,因为会做值比较,a为包装类型,如果需要做值比较就需要拆箱,对a做拆箱
需要执行a.intValue()方法,但是a对null,因此会报空指针错误
额外知识点
1、如果“==”两边都是引用对象类型,则比较的是对象的内存地址是否一样,如果其中一个是基本类型,则需要拆箱做值比较
除了"==",+、-、*、/ 运算都会做拆箱操作
代码
public void test3(){
Integer a = 200;
Integer b = 200;
int c = 200;
System.out.println(a==b);//false
System.out.println(a==c);//true
}
2、当Interger 类型的变量赋值为(-128,128]即装箱操作(valueOf()),用"=="作比较,返回为true,原因是jdk为我们默认生成好了,这256个对应的Integer数组,而不需要重新new新的对象,jdk中对可以枚举的都做了这样的初始化,包括,Integer、Long、Short、Charactor;但是对Double、Float则不会这样初始化操作
代码
public void test4(){
Integer a = 100;
Integer b = 100;
int c = 100;
System.out.println(a==b);//true
System.out.println(a==c);//true
}
3、八种基本类的包装对象的equals(Object o ),不仅要对应类型,还要对比具体的值 ;而对于其他对象类型比较的是内存的地址,但是String类的equals方式是重写了的,是比较的对象的值而不是内存地址
代码
public void test5(){
String[] str1 = {"1"};
String[] str2 = {"1"};
String s1 = "aa";
String s2 = "aa";
String s3 = new String("aa");
System.out.println(str1.equals(str2));//false
System.out.println(s1==s2);//true
System.out.println(s1==s3);//false
System.out.println(s1.equals(s2));//true
System.out.println(s1.equals(s3));//true
}
其中为什么"s1==s2" 返回的是true呢,需要注意,
String s1 = "aa";
实际上是两个步骤,首先创建了常量"aa",然后在创建String s1 ,然后在把s1 指向常量池中"aa" 的内存地址,在执行
String s2 = "aa";
的时候,现在常量池中查找是否有"aa"这个常量,如果有就直接把s2指向"aa"这个常量的内存地址,因此上述代码中s1==s1返回为true