【面試】Java基礎03
【面試】Java基礎03
針對網上提出的常見的Java基礎面試題,在此做下學習筆記,方便後續複習檢視:
注:有些回答可能忘記標出參考出處,侵權請聯絡刪除:-)
- 抽象類和介面有什麼區別?
- short s1 = 1;s1 = s1 + 1;有什麼錯?那麼 short s1 = 1; s1 += 1;呢?有沒有錯誤?
- Integer 和 int 的區別?
- 裝箱和拆箱
- switch 語句能否作用在 byte 上,能否作用在 long 上,能否作用在 String 上?
11. 抽象類和介面有什麼區別?
抽象類:使用abstract修飾,子類用extends繼承;
介面:使用interface修飾,採用implements實現;
建構函式:
- 抽象類中可以定義建構函式(但是抽象類不能被例項化);
- 介面不能定義建構函式;
成員變數:
- 抽象類中的成員許可權可以是 public、預設、protected(抽象類中抽象方法就是為了重寫,所以不能被 private 修飾);
- 而介面中的成員只可以是 public(方法預設:public abstrat、成員變數預設:public static final);
成員方法:
- 抽象類中可以有抽象方法和具體方法,
- 而介面中只能有抽象方法(public abstract),但在 JDK1.8中,允許在介面中包含帶有具體實現的方法,使用 default 修飾,這類方法就是預設方法。
- 抽象類中可以包含靜態方法;
- 介面中不可以包含靜態方法,同樣在JDK1.8 以後可以包含,之前不能包含是因為,介面不可以實現方法,只可以定義方法,所以不能使用靜態方法(因為靜態方法必須實現)。現在可以包含了,只能直接用介面呼叫靜態方法。
- 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 的區別?
- int 是 Java 的八種基本資料型別之一,而 Integer 是 Java 為 int 型別提供的封裝類;
- int 型變數的預設值是 0,Integer 變數的預設值是 null,這一點說明 Integer 可以區分出未賦值和值為 0 的區分;
- Integer 變數必須例項化後才可以使用,而 int 不需要。
關於 Integer 和 int 的比較的延伸:
-
由於 Integer 變數實際上是對一個 Integer 物件的引用,所以兩個通過 new 生成的 Integer 變數永遠是不相等的,因為其記憶體地址是不同的;
Integer i = new Integer(100); Integer j = new Integer(100); System.out.println(i==j); // false
-
Integer 變數和 int 變數比較時,只要兩個變數的值是相等的,則結果為 true。因為包裝類 Integer 和基本資料型別 int 型別進行比較時,Java 會自動拆包裝類為 int,然後進行比較,實際上就是兩個 int 型變數在進行比較;
Integer i = new Integer(100); System.out.println(i==100); // true
-
非 new 生成的 Integer 變數和 new Integer() 生成的變數進行比較時,結果為 false。因為非 new 生成的 Integer 變數指向的是 Java 常量池中的物件,而 new Integer() 生成的變數指向堆中新建的物件,兩者在記憶體中的地址不同;
Integer i = new Integer(100); Integer j = 100; System.out.println(i==j); // false
-
對於兩個非 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:沒有快取
參考:
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