目录
1.自动装箱,自动拆箱
装箱就是自动将基本数据类型转换为包装器类型;拆箱就是 自动将包装器类型转换为基本数据类型。
java的数据类型:
自动装箱:
最主要的就是Integer b=a;这行代码执行了什么?其实这就是自动装箱的过程,上面程序在执行Integer b=a;
的时候调用了Integer.valueOf ( int i ) 方法,`Integer b=a; 这段代码等同于:Integer b=Integer.valueOf ( a ) 。
自动拆箱:
其实 int a=b,这段代码等价于:int a=b.intValue(),来看看inValue()方法到底是什么,下面是源码:、
看看相关的题目:
代码1好理解,a和b指向的是堆的两块不同的区域,所以他们是不相等的,输出fasle。
代码2也好理解,他是一个自动装箱的过程,会调用Integer.valueOf ( int i ) 方法,所以,他们c,d都不会创建新的对象,而是直接从常量池中拿。所以他们都是一样的,输出true.
代码3也是哥自动装箱的过程,调用Integer.valueOf ( int i )方法,判断不在缓存中拿,所以会在堆上创建新的对象,比较的时候当然是fasle.
代码4,int g=59,首先明白这个59是存储在哪里的?由于他是基本的数据类型,所以它是存在栈中的,Integer h=new Integer(59);这个会在堆中就创建一个对象存储的是59,但是由于代码执行到g==h的时候,这时一个是基本类型一个包装类型,他们相比较,h会发生自动拆箱的过程。即调用intValue()方法返回一个int类型,基本类型就是只比较数值,所以输出true。
接下来再看:
这个输出会是什么?
-
public
class Test4 {
-
public static void main(String[] args) {
-
Double i1 =
100.0;
-
Double i2 =
100.0;
-
Double i3 =
200.0;
-
Double i4 =
200.0;
-
-
System.out.println(i1 == i2);
-
System.out.println(i3 == i4);
-
}
-
}
其实只要看看Double的valueOf()方法的实现就知道了:
所以他会输出false,false
注意,Integer、Short、Byte、Character、Long这几个类的valueOf方法的实现是类似的。
Double、Float的valueOf方法的实现是类似的。
好,接下来再看一个题目:这个输出会是什么?
首先第一个没有什么疑问,c和d都来自缓存,所以相等输出true.
第二个e,f的输出也没什么疑问,都会创建新的对象,所以不等,输出false.
第三个可能刚刚看的时候有点懵逼,但是仔细想想就知道答案,首先会执行的是a+b,首先a和b是包装类型,是对象,他们是不可能相加的,所以先要执行拆箱的操作将a,b拆成基本数据类型再做相加的操作,完了之后与c进行比较,c是包装类型,所以c也会自动拆箱进行比较,这儿可能有疑问就是为什么不是自动装箱成包装类型去比较,而是包装类型进行了拆箱操作呢?
看这个例子:
如果最后是装箱操作的话,输出的就是false,所以最后他不是装箱而是拆箱操作。
所以最后输出true.
第四个的其实就是equals()方法和==的区别,equals()和==其实一样,判断的是两个对象是否相等,但是Integer对equals()方法进行了重写,他比较的就是值,他不会进行类型转换。所以执行a+b的时候依然会有一个拆箱的过程,但是指向equals的时候她会有一个装箱的过程。所以输出的是true.
第五个和第三个有点类似,都是转化为基本的数据类型,然后比较数值,所以他们数值是相等的,返回的是true.
第六个也是先拆箱,然后相加运算,但是请注意这个和上一个直接==不同,上面可以拆箱比较数值,而这个equals()方法里面是Object类型的数据,也就是说他要传一个引用类型的参数,所以a+b会装箱成Integerr类型的数据,但是g是Long类型。类型不同就比较不了了。
第七个,对于a+h,先自动触发拆箱,就变成了int类型和long类型相加,这个会触发类型晋升,结果是long类型的,然后会触发装箱过程,就变成Long了。因此比较结果是true。
在项目中,当我们使用对象的比较的时候一般会用到Objects类,
常用方法:
1.public static boolean equals(Object a,Object b):比较对象a和对象b是否相等.
*比较2个对象是否相等,底层依赖对象重写的equals的方法,如果没有重写,则使用Object的equals()
2.public static <T> T requireNonNull(T obj):检查对象obj不为null,如果为null,则抛出空指针异常,否则返回obj本身.
*可以判断对象是否是空对象.限制参数不能为空.
3.public static boolean nonNull(Object obj):判断对象是否为null,不为返回true,否则返回false
4.public static boolean isNull(Object obj):和nonNull()相反.
参考博客:
https://www.cnblogs.com/dolphin0520/p/3780005.html
https://blog.csdn.net/u013309870/article/details/70229983
https://blog.csdn.net/ijwddd/article/details/80557759