[英]Integer.class vs int.class
Integer.class
、 Integer.TYPE
和int.class
之間有什么區別?
接受我
Integer.class
是 Integer (Wrapper) Class 對象的引用int.class
作為int
不是一個類,它是一個原始類型。 Integer.TYPE
指的是什么?正如您所說, Integer.class
是對Integer
類型的Class
對象的引用。
int.class
是,相似性,是對int
類型的Class
對象的引用。 你說得對,這聽起來不對; 作為特例,原語都有一個Class
對象。 如果你想區分foo(Integer value)
和foo(int value)
,它對於反射很有用。
Integer.TYPE
(不是Integer.type
,請注意)只是int.class
的快捷方式。
您可以通過一個簡單的程序了解這一點:
public class IntClasses {
public static void main(String[] args) {
Class<Integer> a = int.class;
Class<Integer> b = Integer.TYPE;
Class<Integer> c = Integer.class;
System.out.println(System.identityHashCode(a));
System.out.println(System.identityHashCode(b));
System.out.println(System.identityHashCode(c));
}
}
示例輸出(每次都會不同,但前兩個總是相同的,第三個幾乎總是不同的):
366712642
366712642
1829164700
來自java.lang.Class.isPrimitive
API
有九個預定義的 Class 對象來表示八種基本類型和 void。 它們由 Java 虛擬機創建,並與它們所代表的原始類型具有相同的名稱,即 boolean、byte、char、short、int、long、float 和 double。
這些對象只能通過以下公共靜態最終變量java.lang.Boolean.TYPE
、 java.lang.Integer.TYPE
等訪問
簡單來說:
int --> 是基元..用於簡單的數學運算。 您不能將它們添加到集合中。
整數 --> 本身就是對象.. 是整數的包裝器。 即,它們可以與集合一起使用(因為它們是對象)。 它們被 GC 作為普通對象收集。
編輯 :
public static void main(String[] args) {
int i = 5;
System.out.println(int.class);
Integer i1 = new Integer(5);
System.out.println(Integer.TYPE);
}
O/P : int
int
所以,基本上,兩者都返回一個整數。 Integer.TYPE 只返回 Integer 類的原始類型。 對於任何包裝類都是如此
Java 通過為每個原始類型定義兩種類型,以精神分裂的方式處理原始類型與類類型。
例如int
是原始類型, Integer
是類類型。 當您使用泛型時,您將被迫使用非原始類型,因此ArrayList<Integer>
是允許的,但ArrayList<int>
不是。
由於您有時想要執行反射,因此這種二元性導致兩個類(您如何檢查方法public int foo ();
)。
假設你有一個類:
public class Foo {
private Integer value;
public int value1 () {
return value;
}
public Integer value2 () {
return value;
}
}
這兩個方法不會總是返回相同的值,因為value2()
可以返回null
而value1()
將拋出運行時錯誤。
對我來說,理解int.class
和Integer.class
的最簡單方法是停止認為Integer
是一個包裝器(這意味着它是“特殊的”)。 事實上,將 int 視為一種特殊情況更容易,也可能更合適。
Integer 只是一個普通的Java 類,與例如String 沒有什么不同。 它派生自Object
,像Object
一樣操作,在運行時您可以創建Integer
的實例,該實例采用類似對象的內存布局,例如,開頭的指針指向Integer.class
,這就是啟用多態運行時的原因java的行為。
Integer
真的沒有什么特別之處。 如果你想象一個 Java 沒有 boolean、int、long 這些原語,而只有 Integer、Boolean、Long 等,那么類型系統實際上是非常一致的。
從概念上講,您可以將int
視為稍后出於性能原因引入的特殊類。 最初,它與 Integer 無關。 在創建 Java 時,為純數字維護類似對象的內存布局對於算術繁重的程序來說非常昂貴。 大多數算術運算甚至根本不涉及多態動態調度。 例如,在數字上調用諸如 toString 之類的方法就不太常見了。
int 是特殊的,因為它是一個類,它的“實例”被放置在內存中,去掉了公共對象結構——只有四個連續的字節,沒有額外的元數據。
因此,您不能執行123.getClass()
因為 int 123 的運行時內存布局沒有類指針。 int.class
確實存在,它與Integer.class
完全無關(還)。 從某種意義上說, int 更類似於 Void ,因為在 Void.class 中確實存在,但是您永遠不能擁有對象 o 其中o.class == Void.class
。
Java 可以在這里解決,int 是 int,Integer 是 Integer。 但是人們意識到,雖然不太常見,但能夠將 int 視為普通 Java 對象仍然非常有用,否則您將始終至少需要維護兩組方法——一組采用普通對象,另一組采用普通對象需要原語 - 即使性能不是你關心的。 在這些場景中,int 實際上表現得像 Integer。 Java 允許這種轉換通過自動裝箱過程自動發生,從而有效地使 int 和 Integer 相關。
但是 int 仍然是 int,而 Integer 仍然是 Integer(例如int.class != Integer.class
)。 但是 Integer.class 中引入了一個額外的字段來表明它與 int.class 相關,即Integer.TYPE
。 所以Integer.TYPE == int.class
。 對我來說Integer.TYPE
只是為了捕捉 Integer 和 int 相關的概念。 如何使用它,或者它是否有用,取決於你。
實際上, int 和 Integer 仍然是重要的不同類型。 例如:
void accept (int value);
void accept (Integer value);
仍然被認為是兩個重載。 因此,在使用反射時,您可以使用 int.class 和 Integer.class 來區分兩者。
當不使用反射或某種形式的元編程時,因為您無法從對象導航到 int.class,所以在您的代碼中很少會看到 int.class 被使用。 有時會讓人感到困惑,因為自動裝箱語法似乎建議您應該獲取 int.class:
int value = 1;
Class c = ((Object)value).getClass();
但這只是一種錯覺,當您執行((Object)value)
,您實際上是在創建一個具有相同值的新 Integer 實例。
我需要明確使用 int.class 和 Integer.class 的唯一時間是構建一個泛型 api <T> T getValue(String name, Class<T> type);
我需要區分是否允許 api 返回 null:
int value = getValue("key", Integer.class); // will potentially throw NPE
int value = getValue("key", int.class); // will never throw NPE
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.