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
答案 0 :(得分:8)
所有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
和无类型。
您可以使用null
执行但不会导致NullPointerException的唯一操作是分配或传递它而不检查它或将其与另一个引用进行比较。
顺便说一句
简而言之:编译器将根据引用的类型选择一个方法,在运行时,执行基于引用的对象的类。在运行时null
被视为任何类型或没有类型,如果您尝试取消引用它,则会得到NullPointerException。
答案 1 :(得分:1)
“==”检查它是否是同一个实例,而不仅仅是“它们是否相等?”。 Java中没有多个null实例的概念。如果将null与null进行比较,则无论何种类型,都将始终返回true。
您之所以无法将null作为参数传递给与具有不同参数类型的另一个方法具有相同名称的方法,是因为任何一种方法都可以成为没有其他类型上下文的候选方法。不是猜测可能是哪一个,而是正确地指出错误。
答案 2 :(得分:1)
请参阅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
是每个引用类型中的有效值。
(将类型视为一组值;值的类型是它所属的集合;“子类型”表示“子集”。)
答案 3 :(得分:0)
鉴于上面的例子,我们可以承认null没有输入:当你调用m1(null)
时,编译器无法确定实际参数的类型,也无法决定调用哪个方法。所有空值都相等而不是类型,因此(null==null)==true
。
答案 4 :(得分:0)
Null没有类型,但引用(到null
或其他任何东西)都有类型。我们可以使用不同的类型声明两个引用变量,但它们引用的null
在两种情况下都是相同的:
Integer a = null;
Double b = null;
在您的示例中,
m1((Integer) null);
编译器使用传递的引用的类型来计算要调用的重载方法,而不是null
值本身的类型。
答案 5 :(得分:0)
在您的示例中,它证明编译器无法识别类型(null)并决定调用哪个方法。所以你必须明确给出类型。 null == null
也将永远为真;无论你做什么演员,它都不会改变或给null一个类型。
这个post对null
有很长的描述。