java中Int与Integer的区别(缓存机制)

tech2022-10-28  120

为什么java中“1000==1000”为false,“100==100”为true呢?

如果你尝试运行以下代码

public class test { public static void main(String[] args) { Integer a=100,b=100; System.out.println(a==b); Integer c=1000,d=1000; System.out.println(c==d); int e=100,f=100; System.out.println(e==f); int g=1000,h=1000; System.out.println(g==h); } }

你会得到

true false true true

为什么会出现不同呢?先来看看java中int和integer的基本知识:

Integer是int的包装类,int则是java的一种基本数据类型 Integer变量必须实例化后才能使用,而int变量不需要 (最新的版本Integer实例化可以直接赋值,如上代码,而不需要使用Integer a=new Integer(100)这种实例化方式)Integer实际是对象的引用,当new一个Integer时,实际上是生成一个指针指向此对象;而int则是直接存储数据值 Integer的默认值是null,int的默认值是0

其次,来看看“==”与“”equals()”的基本知识:

“==”比较的是两个变量本身的值,即两个对象在内存中的首地址

“equals()”比较的是两个变量所包含的内容

在第一个对比中,我们知道,如果两个引用指向同一个对象,用==表示它们是相等的,如果两个引用不同的对象,用==表示它们是不等的,即时它们的内容相同。

那为什么第二个是true呢,这就是有趣的地方,如果你去看Integer.java类,你会发现一个内部私有类IntegerCache.java,它缓存了-128—127之间的所有整数对象。所以事情就成了所有的小整数在内部缓存。

当我们声明Intege c=100的时候,其实在内部做的是Integer i=Integer.valueOf(100),如果值在-128到127之间,他就从高速缓存返回实例。

在第二个对比中,int属于基本类型,基本类型的比较只能够用==来比较,且比较的是基础类型的值,因此在第二组代码中,均为true。

源码:

//自动装箱,将int类型封装为为Integer public static Integer valueOf(int i) { if (i >= IntegerCache.low && i <= IntegerCache.high) return IntegerCache.cache[i + (-IntegerCache.low)]; return new Integer(i); } //Integer中的缓存 private static class IntegerCache { static final int low = -128; static final int high; static final Integer[] cache; static Integer[] archivedCache; static { // high value may be configured by property int h = 127; String integerCacheHighPropValue = VM.getSavedProperty("java.lang.Integer.IntegerCache.high"); if (integerCacheHighPropValue != null) { try { h = Math.max(parseInt(integerCacheHighPropValue), 127); // Maximum array size is Integer.MAX_VALUE h = Math.min(h, Integer.MAX_VALUE - (-low) -1); } catch( NumberFormatException nfe) { // If the property cannot be parsed into an int, ignore it. } } high = h; // high=127,low=-128,全部装存archiveCache中 VM.initializeFromArchive(IntegerCache.class); int size = (high - low) + 1; // Use the archived cache if it exists and is large enough if (archivedCache == null || size > archivedCache.length) { Integer[] c = new Integer[size]; int j = low; for(int i = 0; i < c.length; i++) { c[i] = new Integer(j++); } archivedCache = c; }//装到缓存中 cache = archivedCache; // range [-128, 127] must be interned (JLS7 5.1.7) assert IntegerCache.high >= 127; } private IntegerCache() {} }

 

最新回复(0)