本文为读书笔记
1. 泛型擦除
擦除式泛型的实现几乎只需要在Javac编译器上做出改进即可,不需要改动字节码、不需要改动Java虚拟机,也保证了以前没有使用泛型的库可以直接运行在Java 5.0之上。
泛型擦除的实现:
擦除前:
擦除后:
可见:
java的类型擦除是把T 在编译时直接抹去,编程类似于ArrayList list 这样的裸类型;而在调用的时候进行强制类型转换;
但是问题出现了:
这样的代码目前java是不支持的,想要用基本类型的集合类,得用包装类,那么问题就出现,每次调用集合类都要进行一次拆箱装箱,这无疑是对性能的一种开销;
2. 自动拆箱装箱
装箱就是自动将基本数据类型转换为包装器类型;拆箱就是自动将包装器类型转换为基本数据类型。
以及:
第一个true:
反编译一下看调用了什么:
执行了 Integer.valueof这个static方法
private static class IntegerCache {
static final int low = -128;
static final int high;
static {
int h = 127;
String integerCacheHighPropValue =
sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
if (integerCacheHighPropValue != null) {
try {
int i = parseInt(integerCacheHighPropValue);
i = Math.max(i, 127);
// Maximum array size is Integer.MAX_VALUE
h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
} catch( NumberFormatException nfe) {
// If the property cannot be parsed into an int, ignore it.
}
}
high = h;
}
一般情况下是127
所以可见,返回的是缓存池里池内同一个对象
超过范围:-128-127 之后就不会从缓存池里取了;
故第二个 false 也能解释了;
第三四个true:
调用的是Integer.intValue来获取值,最后判等就行了故为true
**注意 == 是值相等 **
再来看g 由于 拆箱装箱,所以 左边是一个long的 3 == 右边 int 3
相等
最后一个:
调用的是long的equals
public boolean equals(Object obj) {
if (obj instanceof Long) {
return value == ((Long)obj).longValue();
}
return false;
}
很明显不是 Long类型,故false
由此可以得出结论:
数值类型包装类 装箱(设置值) valueof() 拆箱(获取值) xxxValue()
== 值相等的前提是 左右触发了拆箱 ==做值相等,而不是地址相等
equals为重写方法,调用相关基本类型的包装类方法:
首先判断实例类型,再判断值