搞清楚一道關於Integer的面試題

  • 2019 年 10 月 7 日
  • 筆記

請看題1:
public class IntegerDemo {      public static void main(String[] args) {          Integer a = 888;          Integer b = 888;          Integer c = 88;          Integer d = 88;          System.out.println(a == b);          System.out.println(c == d);      }  }

上面這道題輸出:

false  true

因為Java的自動拆箱和自動封箱,那麼

Integer a = 888;

就是相當於

Integer a = new Integer(888);

自然上面的變量a和b都是各自指向不同的對象引用地址。那麼答案就肯定是false。

那為什麼c===d就是指向同一個對象呢?

再來看看,Integer中部分源碼

    //具體源碼部分      public static Integer valueOf(int i) {          //i>=-128&&i<=127          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 {              // high value may be configured by property              int h = 127              //省略無關代碼....              high = h;              //初始化cache數組大小              //cache的大小=127-(-128)+1=256              cache = new Integer[(high - low) + 1];              int j = low;              for(int k = 0; k < cache.length; k++)                  //把-128到127的數字全部轉換成Integer對象                  //並存入到cache數組中。                  cache[k] = new Integer(j++);          }         private IntegerCache() {}      }

面試題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:

public class IntegerDemo {      public static void main(String[] args) {          Integer a = new Integer(88);          a = 99;          System.out.println(a);      }  }

這裡又將輸出多少呢?

繼續看源碼:

public final class Integer extends Number implements Comparable<Integer> {    //final修飾變量,如果是基本數據類型的變量,則其數值一旦在初始化之後便不能更改    //如果是引用類型的變量,則在對其初始化之後便不能再讓其指向另一個對象。    private final int value;    public Integer(int value) {       this.value = value;   }  }

面試題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基礎篇

● 【文章匯總】性能調優篇

● 【文章匯總】設計模式篇

● 【文章匯總】Spring家族篇