您现在的位置是:主页 > news > 上海正规做网站公司/站长工具seo综合查询收费吗
上海正规做网站公司/站长工具seo综合查询收费吗
admin2025/5/14 13:54:08【news】
简介上海正规做网站公司,站长工具seo综合查询收费吗,js素材网站,挂网站需要什么服务器问题引入 Java使用进行引用的比较,使用equals进行对象的比较。在多数情况下,都是使用比较基本数据类型,而使用equals比较对象类型。但Java又为每个基本数据类型建立了相应的包装类,这使得相等的比较稍微复杂了一些,其…
问题引入
Java使用==进行引用的比较,使用equals进行对象的比较。在多数情况下,都是使用==比较基本数据类型,而使用equals比较对象类型。但Java又为每个基本数据类型建立了相应的包装类,这使得相等的比较稍微复杂了一些,其中涉及自动装箱与拆箱的问题。同时,Integer的缓存机制使得比较情况更加复杂。因此,在这里分析一下Integer的自动装箱与比较问题。
自动装箱
自动拆箱和自动装箱是 java的语法糖之一,执行在编译期,会根据代码的语法决定是否进行拆箱和装箱动作。自动装箱使得定义基本数据类型的包装类时,可以直接使用=赋值,而不使用new,如:
Integer a = 5;
在编译时,会根据这种语法,决定进行装箱操作,实际上执行的语句调用了Interger的静态方法:
Integer a = Integer.valueOf(128);
在任何时候,如果涉及到从基本数据类型到其包装类的转换,编译器都会决定进行自动装箱。比如:
Map<String,Integer> map = new HashMap<>();
map.put("a", 1);
由于map中值的类型为Integer,而put将int类型的值放到map中,自动装箱后的语句类似于:
Map<String,Integer> map = new HashMap<>();
map.put("a", Integer.valueOf(1));
自动拆箱
和自动装箱相反,如果将Integer类型的数据赋值给基本数据类型int,就会执行自动拆箱。如:
Integer a = new Integer(5);
int b = a;
在编译时,会根据这种语法,决定进行拆箱操作,实际上执行的语句调用了a的intValue方法:
Integer a = new Integer(5);
int b = a.intValue();
当Integer类型的对象和基本数据类型进行算术或关系运算时,Integer对象也会自动拆箱,比如:
Integer a = new Integer(5);
int b = 6;
Integer c = a + b;
当执行Integer c = a + b;时,编译器发现一个Integer类型和一个int类型进行算术运算,决定对Integer类型进行拆箱。a+b运算的结果实际上是int类型的,将结果赋值给c时又会进行装箱操作。
Integer的缓存机制
Integer的缓存机制使得比较问题更加复杂。上面说过,自动装箱时调用了Integer.valueOf(),这个函数的源码为:
public static Integer valueOf(int i) {if (i >= IntegerCache.low && i <= IntegerCache.high)return IntegerCache.cache[i + (-IntegerCache.low)];return new Integer(i);
}
其中IntegerCache.low=-128,IntegerCache.high=127。这说明valueOf的参数如果介于-128和127之间的话,会返回IntegerCache中的对象,否则会重新new一个对象并返回。
Integer/int的比较
1.两个int类型进行比较,直接使用==就好了。
2.涉及Integer的比较,使用equals总不会出错。如果是两个Integer进行比较,equals当然比较的是各对象的值。如果是一个Integer和一个int比较,只能对Integer对象使用equals方法,这时会涉及自动装箱,比如:
Integer a = 5;
int b = 5;
a.equals(b);
最后一条语句会让b自动装箱,但是equals比较的始终是对象的值,因此不会有问题
3.涉及Integer的比较,如果使用==,情况会变得复杂。
如果是一个Integer和一个int比较,前面说过会进行自动拆箱,Integer对象会变为int类型,相当于两个int的==比较,没有问题。
如果是两个Integer进行比较,这里情况比较复杂。
(1)只要有一个Integer是通过new产生的,一定会得到false。因为new会在堆中分配内存,而==比较的是引用,也就是比较内存地址,只要不是别名引用,一定会得到false
Integer a = new Integer(5);
Integer b = new Integer(5);
Integer c = 5;
a == b // false
a == c // false
(2)两个Integer都是直接赋值产生的,只有被缓存时才能得到true。根据上面valueOf的源码可知,如果值落在-128~127之间,会返回IntegerCache中的对象,对于下面的代码,a和b都指向IntegerCache中的同一对象,因此==会得到true
Integer a = 5;
Integer b = 5;
a == b // true
(3)两个Integer都是直接赋值产生的,但未缓存,会得到false。根据valueOf的源码,如果值不在-128~127之间,会返回new的对象,这时和(1)完全一样。对于下面的代码,a和b都是new出的对象,==会得到false
Integer a = 128;
Integer b = 128;
a == b // false
对于其他基本数据类型及其包装类,也涉及装箱、拆箱以及缓存的机制
包装类型 | 基本数据类型 | 缓存 |
---|---|---|
Boolean | boolean | true,false |
Byte | byte | -128~127 |
Short | short | -128~127 |
Character | char | 0~127 |
Integer | int | -128~127 |
Long | long | -128~127 |
Float | float | 无缓存 |
Double | double | 无缓存 |
启示
可以看出比较的情况还是比较多的,但是如果只使用equals,就不会出现任何问题。因此涉及包装类对象之间值的比较,一定要用equals方法。这也是阿里Java开发手册编程规约中指出的:强制所有包装类对象之间值的比较,全部使用 equals 方法!