记得当初老师告诉我们,尽量用Integer来定义int型字段,因为这样可以防止个别情况出现给int字段赋值null时引起的报错,我觉得有道理,就照做了相信有很多人在对两个Integer型数字判断相等时跟我一样使用“==”号吧,下面给大家看一个神奇的现象:,今天小编就来聊一聊关于integer是不是合法的关键字?接下来我们就一起去研究一下吧!

integer是不是合法的关键字(年轻人容易犯的错)

integer是不是合法的关键字

记得当初老师告诉我们,尽量用Integer来定义int型字段,因为这样可以防止个别情况出现给int字段赋值null时引起的报错,我觉得有道理,就照做了。相信有很多人在对两个Integer型数字判断相等时跟我一样使用“==”号吧,下面给大家看一个神奇的现象:

Integer integera = 1; Integer integerb = 1; Integer integerc = 127; Integer integerd = 127; Integer integere = 128; Integer integerf = 128; System.out.println("integera==integerb:" (integera == integerb)); System.out.println("integerc==integerd:" (integerc == integerd)); System.out.println("integere==integerf:" (integere == integerf)); 运行结果: integera==integerb:true integerc==integerd:true integere==integerf:false

刚开始我满脸疑惑,为什么1可以,127可以,128就不行了呢,与其想破脑袋没有结果,还不如深入源码一探究竟,于是乎我找到了Integer的源码,发现Integer类里面竟然隐藏了一个内部类,是不是这小子搞的鬼呢?

// 如果没看错的话,这个内部类应该跟缓存有关吧 private static class IntegerCache { static final int low = -128; // 最小值-128 static final int high; // 最大值 static final Integer cache[]; // 缓存数组 // 静态块初始化缓存数组 static { // 先设置一个默认最大值为127 int h = 127; // 从启动VM参数-Djava.lang.Integer.IntegerCache.high 获取自定义设置的Integer缓存最大值 String integerCacheHighPropValue = sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high"); // 如果设置了Integer缓存最大值的情况 if (integerCacheHighPropValue != null) { try { // 将Integer缓存最大值转成int int i = parseInt(integerCacheHighPropValue); // 跟127比较取大值,也就是你自定义的最大值只有大于127的时候才会生效 i = Math.max(i, 127); // Integer.MAX_VALUE - (-low) -1 意思是数组的最大长度减去128个负数,再减去一个0,剩下的数跟上面计算过的最大值比较取小作为缓存的最大值 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]; // j初始值为最小值-128 int j = low; // 循环把最小值到最大值之间的数字通过构造方法生成Integer对象并按照从小到大的顺序放到缓存数组中 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() {} }

哦,看明白了,原来是初始化的时候把-128到127(可以通过vm启动参数调整)之间的所有数字创建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对象的时候,只要你传的值在-128到127之间,就直接从缓存中取出Integer对象返回,否则,会new新的Integer对象,到这里我恍然大悟,“ == ”号比较的是对象的地址,-128到127之间两个相同数字是从缓存中拿到的同一个对象,“ == ”自然返回就是true,当不在-128到127之间两个相同数字获取到的是系统new出来的两个新对象,虽然数值相等,但是地址肯定不同,“ == ”返回false也就没啥可大惊小怪的了吧。那如此说来,要判断两个Integer型数字是否相等使用“==”号应该是不规范的,那我们该如何判断两个Integer型数字是否相等呢?正确姿势应该如下:

Integer integera = 1; Integer integerb = 1; Integer integerc = 127; Integer integerd = 127; Integer integere = 128; Integer integerf = 128; //当然前提要有非null判断 System.out.println("integera==integerb:" (integera.equals(integerb))); //当然前提要有非null判断 System.out.println("integerc==integerd:" (integerc.equals(integerd))); //当然前提要有非null判断 System.out.println("integere==integerf:" (integere.equals(integerf))); 运行结果: integera==integerb:true integerc==integerd:true integere==integerf:true

那为啥用equals呢,固有印象中equals不是比较字符串大小吗?啥也不说,上源码:

public boolean equals(Object obj) { if (obj instanceof Integer) { return value == ((Integer)obj).intValue(); } return false; }

哦,原来人家的equals方法是先判断参数如果是Integer型,直接取int值进行比较,那这就没啥可说的了吧,至此,同学们是不是对Integer型数字判断是否相等有了新的认识呢?

,