一、总结一下Java的基本类型和引用类型
特点总结:
引用数据类型的大小统一为4个字节,记录的是其引用对象的地址!
基本数据类型一个字节等于8位:1byte=8bit.
二、拆箱,装箱
简单来说:
自动装箱就是自动将基本数据类型转换为包装器类型;
自动拆箱就是自动将包装器类型转换为基本数据类型。
三、int和Integer的区别
Integer是int的包装类,int则是java的一种基本数据类型
Integer变量必须实例化后才能使用,而int变量不需要
Integer实际是对象的引用,当new一个Integer时,实际上是生成一个指针指向此对象;而int则是直接存储数据值
Integer的默认值是null,int的默认值是0
四、==与equals()的区别
==:
如果是基本数据类型的比较,是值的比较
如果是引用类型的比较,⽐较的是两个引⽤是否指向相同的对象,也就是比较内存地址是否相同
equals():
equals 是比较内存地址上面的值是否相同
五、代码比较
1、new两个Integer进行比较
public class Test { public static void main(String[] args) { Integer a = new Integer(10); Integer b = new Integer(10); System.out.println(a == b); // false System.out.println(a.equals(b)); // true } }
总结:a == b是比较内存地址是否相同,因为new了两个对象,所以为false。
a.equals(b)是比较内存地址上面的值是否相同,所以为true
2、new一个Integer和一个int类型的比较
public class Test { public static void main(String[] args) { Integer a = new Integer(10); int b = 10; System.out.println(a == b); // true System.out.println(a.equals(b)); // true } }
总结:包装类Integer和基本数据类型int比较时,java会自动拆包装为int,然后进行比较,实际上就变为两个int变量的比较
3、new一个Integer,直接赋值一个Integer
public class Test { public static void main(String[] args) { Integer a = new Integer(10); Integer b = 10; System.out.println(a == b); // false System.out.println(a.equals(b)); // true } }
总结:因为非new生成的Integer变量指向的是java常量池中的对象,而new Integer()生成的变量指向堆中新建的对象,两者在内存中的地址不同,所以为false
4、两个Integer直接赋值
public class Test { public static void main(String[] args) { Integer a = 10; Integer b = 10; System.out.println(a == b); // true System.out.println(a.equals(b)); // true } }
总结:因为全部指向常量池中,所以全是true。
5、当值大于127时
看下边代码
public class Test { public static void main(String[] args) { Integer a = 128; Integer b = 128; System.out.println(a == b); // false System.out.println(a.equals(b)); // true } }
总结:原因得从源码说起:看一下Integer的源码
static final int low = -128; private static class IntegerCache { static final int low = -128; static final int high; static final Integer cache[]; static { // high value may be configured by property 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; cache = new Integer[(high - low) + 1]; int j = low; for(int k = 0; k < cache.length; k++) cache[k] = new Integer(j++); // range [-128, 127] must be interned (JLS7 5.1.7) assert IntegerCache.high >= 127; } private IntegerCache() {} } public static Integer valueOf(int i) { if (i >= IntegerCache.low && i <= IntegerCache.high) return IntegerCache.cache[i + (-IntegerCache.low)]; return new Integer(i); }
当i大于等于最小值-128并且小于等于最大值127时,会调用IntegerCache.cache(),进行缓存,所以第一个两个true是因为第一次添加到了缓存中,第二次获取的也是缓存中的数值。所以打印了两个true。
当大于127时,代码底层实际上是new 了两个Integer所以其实是再对内存中存在两个不同的对象。