八大基本数据类型均有对应的包装类 byte、short、int、long、float、double、char、boolean分别对应Byte、Short、Integer、Long、Float、Double、Character、Boolean
包装类型的出现是为了方便基本数据类型能够和其它对象结合在一起使用,比如一些常用的集合List和Set等要求存放的值必须为对象。而包装类的自动拆装和封装机制则使得包装类和基本数据类型互换变得很便利。至于包装类和基本数据类型之间的区别就不用赘述了,主要是初始值,使用方式,存储方式不同等等。
下面通过一些案例来剖析包装类的一些特性。 Java中比较两个值是否相等有两种方式 1. If(a==b) 2. If(a.equals(b)) 对于第一种方式,如果a,b均是数值则会直接比较值的大小,相等则返回true,如果是对象则会比较两个对象的引用是否相同。 对于第二种方式可以看下Object的源码
代码语言:javascript复制public boolean equals(Object obj) {
return (this == obj);
}
实际上也是调用了第一种方式来进行判断。但是实际上很多类都对equals方法做了覆写。比如像Integer的包装类
代码语言:javascript复制ublic boolean equals(Object obj) {
if (obj instanceof Integer) {
return value == ((Integer)obj).intValue();
}
return false;
}
Integer的equals方法会先判断实例是否是Integer类型,再判断数值是否相等。Double,Float等包装类的equals方法也是如此。
代码语言:javascript复制Long l1 = 128L;
Long l2 = 128L;
System.out.println(l1==l2); //1
System.out.println(l1==128L); //2
Long l3 = 127L;
Long l4 = 127L;
System.out.println(l3==l4); //3
System.out.println(l3==127L); //4
Double d1 = 100.0;
Double d2 = 100.0;
Double d3 = 200.0;
Double d4 = 200.0;
System.out.println(d1==d2); //5
System.out.println(d3==d4); //6
要想知道以上程序的输出,先要了解一个知识点。对于Integer、Short、Byte、Character、Long 这些包装类,都有一个常量池,常量池的范围是-128~127之间。如果定义的包装类的值在这个范围内,则会直接返回内部缓存池中已经存在的对象的引用,而对于浮点型Float和Double这样的包装类,没有常量池机制,不管传入的值是多少,都会new一个新的对象。
结合上面讲解的==号的比较机制,可以得出1的输出是false,3的输出是true,5,6的输出是false。1中的l1和l2的定义的值已经超出了常量池的范围,所以l1和l2是不同对象的引用。对于3,l3和l4定义的值在常量池的范围内,所以是同一个对象的引用,且值也相等,所以结果为true,而5和6是浮点型的封装类,创建了不同的对象,结果为false。2和4的输出结果均是true,两者机制一样,如果==比较的两边一个是表达式或者数值,一个是包装类,则包装类会自动拆装返回数值型的结果。
再来看一个案例
代码语言:javascript复制Integer a = 1;
Integer b = 2;
Integer c = 3;
Integer d = 3;
Integer e = 321;
Integer f = 321;
Long g = 3l;
Long h = 2l;
System.out.println(c == d); //1.true
System.out.println(e == f); //2.false
System.out.println(c == (a b)); //3.true
System.out.println(c.equals(a b)); //4.true
System.out.println(g == (a b)); //5.true
System.out.println(g.equals(a b)); //6.false
System.out.println(g.equals(a h)); //7.true
Integer i = 444;
int j = 444;
System.out.println(i==j); //8.true
System.out.println(i.equals(j)); //9.true
对于1,2没什么好讲的,对于3,(a b)这个表达式返回的值是int型,c会自动拆装成int型,值相等为true。对于4,(a b)返回值为int型,作为参数传入equals方法里面,被转换成Integer类(可以自己手动实践打印一下),类型相同值相等结果为true。对于5,a b返回值为int,g自动拆装,数值相等结果为true。对于6,a b返回值为int,作为参数传入equals方法中被封装成Integer,类型不一致,结果为false。对于7,a h结果为long型(h是long,会隐式转换成long型),作为参数传入equals方法中,封装厂Long,类型相同值相等,结果为true。对于8,i自动拆装,值相等,结果为true。对于9,类型相同值相等,结果为true。
声明:以上代码均源自网上,非本人原创,只是加上了自己的理解。