[英]Comparison of two null objects from two different types
public void m1(Integer f) {
...
}
public void m1(Float f) {
...
}
public void main() {
m1(null); // error: the method m1(Integer) is ambiguous for the type Main
m1((Integer) null); // success
}
鑒於上面的例子,我們可以在某些方面承認輸入了null
。 那么為什么以下行打印為true
? 當然o1
和o2
都沒有值(即null
),但它們不是同一類型( Integer
vs Float
)。 我首先認為會打印false
。
Integer i = null;
Object o1 = (Object) i;
Float f = null;
Object o2 = (Object) f;
System.out.println(o1 == o2); // prints true
// in short:
System.out.println(((Object) ((Integer) null)) == ((Object) ((Float) null))); // prints true
所有null
值都是無類型的並且是相等的。 您可以將它傳遞給不同的引用類型,但它對於比較目的沒有區別。
它不是鍵入的null
值,而是對可以鍵入的null的引用。
一個常見的問題是這里發生了什么
class A {
public static void hello() { System.out.println("Hello World"); }
public static void main(String... args) {
A a = null;
a.hello();
System.out.println("a is an A is " + (a instanceof A)); // prints false.
}
}
編譯器看到的類型a
作為A
所以靜態方法被調用。 但引用的值為null
且無類型。
在不導致NullPointerException的情況下,您可以使用null
執行的唯一操作是分配或傳遞它而不檢查它或將其與另一個引用進行比較。
BTW
簡而言之:編譯器將根據引用的類型選擇方法,在運行時,執行基於引用的對象的類。 在運行時, null
被視為任何類型或沒有類型,如果您嘗試取消引用它,則會得到NullPointerException。
Java中的“==”檢查它是否是同一個實例,而不僅僅是“它們是否相等?”。 Java中沒有多個null實例的概念。 如果將null與null進行比較,則無論何種類型,都將始終返回true。
之所以你不能將null作為參數傳遞給與具有不同參數類型的另一個方法具有相同名稱的方法,是因為任何一種方法都可以成為沒有其他類型上下文的候選方法。 它不是猜測可能是哪一個,而是正確地表示錯誤。
見http://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.1
null
屬於“null類型”。 “null type”只有一個值 - null
。
null類型是每個引用類型的子類型。 因此我們可以做到
Integer i = null;
(Integer)null
換句話說, null
是每個引用類型中的有效值。
(將類型視為一組值;值的類型是它所屬的集合;“子類型”表示“子集”。)
鑒於上面的例子,我們可以承認null不是類型的:當你調用m1(null)
,編譯器無法確定實際參數的類型,也無法決定調用哪個方法。 所有空值都相等而不是類型,因此(null==null)==true
。
Null沒有類型,但引用 ( null
或其他任何內容)具有類型。 我們可以使用不同的類型聲明兩個引用變量,但它們引用的null
在兩種情況下都是相同的:
Integer a = null;
Double b = null;
在你的例子中,
m1((Integer) null);
編譯器使用它傳遞的引用類型來計算要調用的重載方法,而不是null
值本身的類型。
在您的示例中,它證明編譯器無法標識類型(null)並決定調用哪個方法。 所以你必須明確給出類型。 null == null
也將始終為true; 無論你做什么演員,它都不會改變或給null一個類型。
這篇文章對null
有很長的描述。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.