搞清楚一道关于Integer的面试题【华为云技术分享】
请看题1:
1 public class IntegerDemo { 2 public static void main(String[] args) { 3 Integer a = 888; 4 Integer b = 888; 5 Integer c = 88; 6 Integer d = 88; 7 System.out.println(a == b); 8 System.out.println(c == d); 9 } 10 }
上面这道题输出:
1 false 2 true
因为Java的自动拆箱和自动封箱,那么
Integer a = 888;
就是相当于
Integer a = new Integer(888);
自然上面的变量a和b都是各自指向不同的对象引用地址。那么答案就肯定是false。
那为什么c===d就是指向同一个对象呢?
再来看看,Integer中部分源码
1 //具体源码部分 2 public static Integer valueOf(int i) { 3 //i>=-128&&i<=127 4 if (i >= IntegerCache.low && i <= IntegerCache.high) 5 return IntegerCache.cache[i + (-IntegerCache.low)]; 6 return new Integer(i); 7 } 8 //Integer的静态内部类 9 private static class IntegerCache { 10 static final int low = -128; 11 static final int high; 12 //常量数组 13 static final Integer cache[]; 14 15 static { 16 // high value may be configured by property 17 int h = 127 18 //省略无关代码.... 19 high = h; 20 //初始化cache数组大小 21 //cache的大小=127-(-128)+1=256 22 cache = new Integer[(high - low) + 1]; 23 int j = low; 24 for(int k = 0; k < cache.length; k++) 25 //把-128到127的数字全部转换成Integer对象 26 //并存入到cache数组中。 27 cache[k] = new Integer(j++); 28 } 29 private IntegerCache() {} 30 }
面试题2:
public class IntegerDemo {
public static void main(String[] args) {
Integer a = new Integer(88);
test(a);
System.out.println(a);
}
private void test(Integer integer){
integer=new Integer(99);
}
}
上面应该输出多少呢?
面试题3:
1 public class IntegerDemo { 2 public static void main(String[] args) { 3 Integer a = new Integer(88); 4 a = 99; 5 System.out.println(a); 6 } 7 }
这里又将输出多少呢?
继续看源码:
1 public final class Integer extends Number implements Comparable<Integer> { 2 //final修饰变量,如果是基本数据类型的变量,则其数值一旦在初始化之后便不能更改 3 //如果是引用类型的变量,则在对其初始化之后便不能再让其指向另一个对象。 4 private final int value; 5 public Integer(int value) { 6 this.value = value; 7 } 8 }
面试题3中的a=99相当于a=new Integer(99);重新给把一个新的对象引用地址给了a,所以a变了,最后输出是99。
那么面试题2呢?
我们都知道在Java中,Java 只有值传递,只不过值传递分为:内存中数值的值传递以及内存地址数值的值传递,传递一个Integer变量参数进去,实际上是构建了一个副本,通过这个副本我们只能去修改原来Integer变量的非final成员变量(假如有的话,也可以是其他类型),上面也说了,如果去修改Integer类型的final变量,那么是会新new一个Integer变量,去覆盖这个变量副本,所以原来的Integer a变量还是原来的,仅仅是test这个方法里的副本变量变了,这么理解就清楚了。所以面试题2 输出88。
来源: Java后端技术栈
HDC.Cloud 华为开发者大会2020 即将于2020年2月11日-12日在深圳举办,是一线开发者学习实践鲲鹏通用计算、昇腾AI计算、数据库、区块链、云原生、5G等ICT开放能力的最佳舞台。