1. 程式人生 > 實用技巧 >【面試】Java基礎03

【面試】Java基礎03

【面試】Java基礎03

針對網上提出的常見的Java基礎面試題,在此做下學習筆記,方便後續複習檢視:

注:有些回答可能忘記標出參考出處,侵權請聯絡刪除:-)

  1. 抽象類和介面有什麼區別?
  2. short s1 = 1;s1 = s1 + 1;有什麼錯?那麼 short s1 = 1; s1 += 1;呢?有沒有錯誤?
  3. Integer 和 int 的區別?
  4. 裝箱和拆箱
  5. switch 語句能否作用在 byte 上,能否作用在 long 上,能否作用在 String 上?

11. 抽象類和介面有什麼區別?

抽象類:使用abstract修飾,子類用extends繼承;

介面:使用interface修飾,採用implements實現;

建構函式:

  1. 抽象類中可以定義建構函式(但是抽象類不能被例項化);
  2. 介面不能定義建構函式;

成員變數:

  1. 抽象類中的成員許可權可以是 public、預設、protected(抽象類中抽象方法就是為了重寫,所以不能被 private 修飾);
  2. 而介面中的成員只可以是 public(方法預設:public abstrat、成員變數預設:public static final);

成員方法:

  1. 抽象類中可以有抽象方法和具體方法,
  2. 而介面中只能有抽象方法(public abstract),但在 JDK1.8中,允許在介面中包含帶有具體實現的方法,使用 default 修飾,這類方法就是預設方法。
  3. 抽象類中可以包含靜態方法;
  4. 介面中不可以包含靜態方法,同樣在JDK1.8 以後可以包含,之前不能包含是因為,介面不可以實現方法,只可以定義方法,所以不能使用靜態方法(因為靜態方法必須實現)。現在可以包含了,只能直接用介面呼叫靜態方法
  5. JDK1.8中,介面仍然不可以包含靜態程式碼塊。

12. short s1 = 1;s1 = s1 + 1;有什麼錯?那麼 short s1 = 1; s1 += 1;呢?有沒有錯誤?

對於 short s1 = 1; s1 = s1 + 1; 來說,在 s1 + 1 運算時會自動提升表示式的型別為 int ,那麼將 int 型值賦值給 short 型變數,s1 會出現型別轉換錯誤。

對於 short s1 = 1; s1 += 1; 來說,+= 是 Java 語言規定的運算子,Java 編譯器會對它進行特殊處理,因此可以正確編譯。

13. Integer 和 int 的區別?

  1. int 是 Java 的八種基本資料型別之一,而 Integer 是 Java 為 int 型別提供的封裝類;
  2. int 型變數的預設值是 0,Integer 變數的預設值是 null,這一點說明 Integer 可以區分出未賦值和值為 0 的區分;
  3. Integer 變數必須例項化後才可以使用,而 int 不需要。

關於 Integer 和 int 的比較的延伸:

  1. 由於 Integer 變數實際上是對一個 Integer 物件的引用,所以兩個通過 new 生成的 Integer 變數永遠是不相等的,因為其記憶體地址是不同的;

    Integer i = new Integer(100);
    Integer j = new Integer(100);
    System.out.println(i==j);  // false
    
  2. Integer 變數和 int 變數比較時,只要兩個變數的值是相等的,則結果為 true。因為包裝類 Integer 和基本資料型別 int 型別進行比較時,Java 會自動拆包裝類為 int,然後進行比較,實際上就是兩個 int 型變數在進行比較;

    Integer i = new Integer(100);
    System.out.println(i==100);  // true
    
  3. 非 new 生成的 Integer 變數和 new Integer() 生成的變數進行比較時,結果為 false。因為非 new 生成的 Integer 變數指向的是 Java 常量池中的物件,而 new Integer() 生成的變數指向堆中新建的物件,兩者在記憶體中的地址不同;

    Integer i = new Integer(100);
    Integer j = 100;
    System.out.println(i==j);  // false
    
  4. 對於兩個非 new 生成的 Integer 物件進行比較時,如果兩個變數的值在區間 [-128, 127] 之間,則比較結果為 true,否則為 false。Java 在編譯 Integer i = 100 時,會編譯成 Integer i = Integer.valueOf(100),而 Integer 型別的 valueOf 的原始碼如下所示:

    Integer i = 127;
    Integer j = 127;
    System.out.println(i==j);  // true
    
    Integer i = 128;
    Integer j = 128;
    System.out.println(i==j);  // false
    
    // 原始碼
    public static Integer valueOf(int i) {
        if (i >= IntegerCache.low && i <= IntegerCache.high)
            return IntegerCache.cache[i + (-IntegerCache.low)];
        return new Integer(i);
    }
    

    從上面的程式碼中可以看出:Java 對於 [-128, 127] 之間的數會進行快取,比如:Integer i = 127,會將 127 進行快取,下次再寫 Integer j = 127 的時候,就會直接從快取中取出,而對於這個區間之外的數就需要 new 了。

針對上述第4點,引申出包裝類的快取:

  • Boolean:全部快取
  • Byte:全部快取
  • Character:<= 127 快取
  • Short:-128 ~ 127 快取
  • Long:-128 ~ 127 快取
  • Integer:-128 ~ 127 快取
  • Float:沒有快取
  • Doulbe:沒有快取

參考:

https://blog.csdn.net/aoxiangzhe/article/details/81297157

https://www.cnblogs.com/javatech/p/3650460.html

14. 裝箱和拆箱

自動裝箱是 Java 編譯器在基本資料型別和對應得包裝類之間做的一個轉化。比如:把 int 轉化成 Integer,double 轉化成 Double 等等。反之就是自動拆箱。

原始型別:boolean、char、byte、short、int、long、float、double

封裝型別:Boolean、Character、Byte、Short、Integer、Long、Float、Double

Integer a = 1;
Integer b = 2;
Integer c = 3;
Integer d = 3;
Integer e = 321;
Integer f = 321;
Long g = 3L;
Long h = 2L;

System.out.println(c==d);  // 有快取存在,結果為true
System.out.println(e==f);  // 超出快取了,地址比較,結果為false
System.out.println(c==(a+b));  // a+b進行了算數運算,觸發自動拆箱,因此比較的是數值是否相等,結果為true
System.out.println(c.equals(a+b));  // a+b算數運算,自動拆箱,使用equals時自動裝箱為Integer型別的資料,故結果為true
System.out.println(g==(a+b));  // a+b算數運算,自動拆箱,因此比較的是數值是否相等,結果為true
System.out.println(g.equals(a+b));  // a+b算數運算,自動拆箱,使用equals時自動裝箱為Integer型別的資料,g為Long型別的資料,型別不一致,因此結果為false
System.out.println(g.equals(a+h));  // 由於此時h為Long型別資料,因此裝箱為Long型別資料,比較結果為true

參考:https://blog.csdn.net/qq_35571554/article/details/82876774

15. switch 語句能否作用在 byte 上,能否作用在 long 上,能否作用在 String 上?

在 switch(expr 1) 中,expr1 只能是一個整數表示式或者列舉常量。

而整數表示式可以是 int 基本資料型別或者 Integer 包裝型別。由於byte、short、char 都可以隱式轉換為 int,所以,這些型別以及這些型別的包裝型別也都是可以的。

而 long 和 String 型別都不符合 switch 的語法規定,並且不能被隱式的轉換為 int 型別,所以,它們不能作用於 switch 語句中。不過,需要注意的是在 JDK1.7 版本之後 String 就可以作用在 Switch 上了。

參考:https://blog.csdn.net/u012110719/article/details/46316659