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
}
Given the above example, we can admit in some ways that null
is typed. So why do the following lines print true
? Sure o1
and o2
both have no value (i.e. null
), but they aren't from the same type (Integer
vs Float
). I firstly thought false
would have been printed.
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
All null
values are untyped and are equal. You can pass it to different reference types but it makes no difference for comparison purposes.
It is not the null
value which is typed but the reference to the null which can be typed.
A common question is what happens here
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.
}
}
The compiler sees the type of a
as an A
so the static method is called. But the value referenced is null
and untyped.
The only operations you can perform with null
without causing a NullPointerException is to assign or pass it without examining it or comparing it with another reference.
BTW
In short: The compiler will select a method based on the type of the reference, at runtime the execution is based on the class of the object referenced. At runtime null
is treated as any type or no type or you get a NullPointerException if you try to dereference it.
"==" in Java checks to see if it is the same instance rather than simply "are they equal?". There is no concept of multiple instances of null in Java. If you compare null to null, you will always receive true regardless of type.
The reason why you cannot then pass null as an argument to a method with the same name as another with different parameter types is because either method could be a candidate to be called without further type context. Rather than guess which one that might be, it correctly indicates an error.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With