1. 以下 Integer 代碼輸出的結果是?
Integer age = 10; Integer age2 = 10; Integer age3 = 133; Integer age4 = 133; System.out.println((age == age2) + "," + (age3 == age4));
答:true,false
2. 以下 Double 代碼輸出的結果是?
Double num = 10d; Double num2 = 10d; Double num3 = 133d; Double num4 = 133d; System.out.println((num == num2) + "," + (num3 == num4));
答:false,false
3. 以下程序輸出結果是?
int i = 100; Integer j = new Integer(100); System.out.println(i == j); System.out.println(j.equals(i));
答:true,true
題目分析:有人認為這和 Integer 高速緩存有關系,但你發現把值改為 10000 結果也是 true,true
,這是因為 Integer 和 int 比較時,會自動拆箱為 int 相當於兩個 int 比較,值一定是 true,true
。
4. 以下程序執行的結果是?
final int iMax = Integer.MAX_VALUE; System.out.println(iMax + 1);
答:-2147483648(--Integer.MAX_VALUE)
題目解析:這是因為整數在內存中使用的是補碼的形式表示,最高位是符號位 0 表示正數,1 表示負數,當執行 +1 時,最高位就變成了 1,結果就成了 -2147483648。
5. 以下程序執行的結果是?
Set<Short> set = new HashSet<>(); for (short i = 0; i < 5; i++) { set.add(i); set.remove(i - 1); } System.out.println(set.size());
答:5
題目解析:Short 類型 -1 之后轉換成了 Int 類型,remove() 的時候在集合中找不到 Int 類型的數據,所以就沒有刪除任何元素,執行的結果就是 5。
6. short s=2;s=s+1;
會報錯嗎?short s=2;s+=1;
會報錯嗎?
答:s=s+1 會報錯,s+=1 不會報錯,因為 s=s+1 會導致 short 類型升級為 int 類型,所以會報錯,而 s+=1 還是原來的 short 類型,所以不會報錯。
7. float f=3.4;
會報錯嗎?為什么?
答:會報錯,因為值 3.4 是 double 類型,float 類型級別小於 double 類型,所以會報錯。如下圖所示:
8. 為什么需要包裝類?
答:需要包裝類的原因有兩個。
① Java 的設計思想是萬物既對象,包裝類體現了面向對象的設計理念;
② 包裝類包含了很多屬性和方法,比基本數據類型功能多,比如提供的獲取哈希值(hashCode)或獲取類(getClass)的方法等。
9. 基本類 int 和包裝類 Integer,在 -128~127 之間都會復用已有的緩存對象,這種說法正確嗎?
答:不正確,只有包裝類高頻區域數據才有緩存。
10. 包裝類 Double 和 Integer 一樣都有高頻區域數據緩存,這種說法正確嗎?
答:不正確,基本數據類型的包裝類只有 Double 和 Float 沒有高頻區域的緩存。
11. 包裝類的值比較要使用什么方法?
答:包裝類因為有高頻區域數據緩存,所以推薦使用 equals() 方法進行值比較。
12. 包裝類有哪些功能?
答:包裝類提供的功能有以下幾個。詳見正文“包裝類型”部分內容。
- 功能豐富:包裝類包含了有 hashCode、getClass 、max、min 等方法;
- 可定義泛型類型參數:例如
List<Integer> list = new ArrayList<>();
; - 序列化:包裝類實現了 Serializable 接口,所以包裝類天然支持序列化和反序列化;
- 類型轉換:包裝類提供了方便的類型轉換方法,比如 Integer 的 parseInt() 方法;
- 高頻區域數據緩存:高頻區域可使用已有的緩存對象。
13. 泛型可以為基本類型嗎?為什么?
答:泛型不能使用基本數據類型。泛型在 JVM(Java虛擬機)編譯的時候會類型檫除,比如代碼 List<Integer> list
在 JVM 編譯的時候會轉換為 List list
,因為泛型是在 JDK 5 時提供的,而 JVM 的類型檫除是為了兼容以前代碼的一個折中方案,類型檫除之后就變成了 Object,而 Object 不能存儲基本數據類型,但可以使用基本數據類型對應的包裝類,所以像 List<int> list
這樣的代碼是不被允許的,編譯器階段會檢查報錯,而 List<Integer> list
是被允許的。
14. 選擇包裝類還是基本類的原則有哪些?
答:我們知道正確的使用包裝類,可以提高程序的執行效率,可以使用已有的緩存,一般情況下選擇基本數據類型還是包裝類原則有以下幾個。
① 所有 POJO 類屬性必須使用包裝類;
② RPC 方法返回值和參數必須使用包裝類;
③ 所有局部變量推薦使用基本數據類型。
15. 基本數據類型在 JVM 中一定存儲在棧中嗎?為什么?
答:基本數據類型不一定存儲在棧中,因為基本類型的存儲位置取決於聲明的作用域,來看具體的解釋。
- 當基本數據類型為局部變量的時候,比如在方法中聲明的變量,則存放在方法棧中的,當方法結束系統會釋放方法棧,在該方法中的變量也會隨着棧的銷毀而結束,這也是局部變量只能在方法中使用的原因;
- 當基本數據類型為全局變量的時候,比如類中的聲明的變量,則存儲在堆上,因為全局變量不會隨着某個方法的執行結束而銷毀。
16. 以下程序執行的結果是?
Integer i1 = new Integer(10); Integer i2 = new Integer(10); Integer i3 = Integer.valueOf(10); Integer i4 = Integer.valueOf(10); System.out.println(i1 == i2); System.out.println(i2 == i3); System.out.println(i3 == i4);
答:false,false,true
題目解析:new Integer(10) 每次都會創建一個新對象,Integer.valueOf(10) 則會使用緩存池中的對象。
17. 3*0.1==0.3 返回值是多少?
答:返回值為:false。
題目解析:因為有些浮點數不能完全精確的表示出來,舉個栗子:
System.out.println(3 * 0.1);
返回的結果是:0.30000000000000004。