以下源码基于JDK8。
举个例子
short s1 = 1;
s1 = s1 + 1;有什么错?
short s1 = 1;
s1 += 1; 有什么错?
复制代码
-
对于
short s1 = 1; s1 = s1 + 1;
由于s1+1
运算时会自动提升表达式的类型,所以结果是int
型,再赋值给short
类型s1
时,编译器将报告需要强制转换类型的错误。 -
对于
short s1 = 1; s1 += 1;
由于+=
是java
语言规定的运算符,java
编译器会对它进行特殊处理,s1 = (short) (s1 + 1);
因此 可以正确编译。
不用看了,这里没有表情包。
再举个例子
public class TypeConvert {
public static void main(String[] args) {
// 字面量属于 double 类型
// 不能直接将 1.1 直接赋值给 float 变量,因为这是向下转型
// Java 不能隐式执行向下转型,因为这会使得精度降低。
// float f = 1.1; // 这里会报错
float f = 1.1f;
}
}
复制代码
不用看了,这里也没有表情包。
Integer的缓存池
public class IntegerPackDemo {
public static void main(String[] args) {
Integer x = 3; // 装箱,3自动包装为Integer
int z = x; // 拆箱 x 拆箱为基本类型
Integer y = 3;
System.out.println(x == y); // true 基本类型比较可用==
// -------------------------
Integer a = new Integer(3);
Integer b = new Integer(3);
System.out.println(a == b); // false 老生常谈了,就不说为什么了
System.out.println(a.equals.(b)); // true // 这里是用重写了equals方法,比较的是值,而不是对象的地址
// ------------------------
// 缓存池
Integer aa = Integer.valueOf(123);
Integer bb = Integer.valueOf(123);
System.out.println(aa == bb); // true
}
}
复制代码
别慌
Integer的equals
public boolean equals(Object obj) {
if (obj instanceof Integer) {
return value == ((Integer)obj).intValue(); // 这里比的就是值了
}
return false;
}
复制代码
valueOf源码
// 源码描述:
// This method will always cache values in the range -128 to 127,
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high) // 条件
return IntegerCache.cache[i + (-IntegerCache.low)];// 取缓存,
// Integer的源码中:
// static final int high; 127
// static final int low = -128; 因此,IntegerCache.low = -128
return new Integer(i);
}
复制代码
IntegerCache源码较长,有兴趣可以去源码阅读一波
当使用自动装箱方式创建一个Integer对象时,当数值在-128 ~127时,会将创建的 Integer 对象缓存起来,当下次再出现该数值时,直接从缓存中取出对应的Integer对象。所以上述代码中,x和y引用的是相同的Integer对象。