2

I want to know why the below code doesn't work :

System.out.print(null);    
response.getWriter().print(null);

But the below ones work :

String s = null;
System.out.print(s);
response.getWriter().print(s);

Whats the difference between passing a null as compared to passing a reference as null ?

EDITED : Doesn't work fore mentioned indicates to compilation error .

AllTooSir
  • 48,828
  • 16
  • 130
  • 164
  • 4
    Define "doesn't work." – Matt Ball Feb 09 '13 at 03:41
  • Interesting. I suppose that just passing a `null` makes it so that the program treats it as nothing while passing a `null` through a reference works since it's basically showing that the variable itself has no value. – David Feb 09 '13 at 03:43
  • the initial null isnt bound to an object. The second is a string which contains null data. Likely this would return the same as "" which would be accepted by the compiler fine – RyanS Feb 09 '13 at 03:43
  • 1
    "Doesn't work" == "Doesn't compile" or "Doesn't work" == "Does not run"? – Philip Tenn Feb 09 '13 at 03:43
  • @RyanS an empty string is decidedly different from a null string. – Matt Ball Feb 09 '13 at 03:43
  • The System.out.println(someObjectRefrence) actually invokes toString() method and in-case your passed reference does not override one, The default implementation of Object class is invoked. – Anupam Saini Feb 09 '13 at 03:46

3 Answers3

9

This is because you can pass an Object or a String. Since null can fit in both, the compiler doesn't know which method to use, leading to compile error.

Methods definitions:

Instead, if you provide an Object or a String variable (even if it has null value), the compiler would know which method to use.

EDIT: This is better explained in this answer. As to the internal link pointing to the Java specification, you can read it here, and this case would suit here:

The informal intuition is that one method is more specific than another **if any invocation handled by the first method could be passed on to the other one without a compile-time type error.

It is possible that no method is the most specific, because there are two or more methods that are maximally specific.

Community
  • 1
  • 1
Luiggi Mendoza
  • 85,076
  • 16
  • 154
  • 332
  • 2
    This is called "overloading" – Ryan Amos Feb 09 '13 at 03:46
  • I don't think that it's that it could be either, but it's not either. `System.out.println()` expects something non-null. – Stephen Feb 09 '13 at 03:51
  • @Raufio if you test the 2nd code block provided by OP (without the `response...` part), in a simple `public static void main(String[] args)` method, the program will print *null* and terminate with no problems. – Luiggi Mendoza Feb 09 '13 at 03:54
  • @Luiggi: Is it really that ambiguous for the compiler ? Since null is a defined keyword in Java , designers of the compiler know that if its null they have to print null , doesn't matter whether its a String reference or Object reference ! Null is Class agnostic !! – AllTooSir Feb 09 '13 at 03:55
  • @LuiggiMendoza Yeah, because it is a `null` string, not just `null`. If you cast `null` to anything else it will work. – Stephen Feb 09 '13 at 03:55
  • @noob yeah, but as explained in Raufio's answer, `null` doesn't have a type, it could be a `String`, an `Object` or anything else that's not a primitive, so it leads to confusion to the compiler – Luiggi Mendoza Feb 09 '13 at 04:04
  • 1
    @LuiggiMendoza It's for a deeper understanding about how the error occurs, not just the surface level of it. – Ryan Amos Feb 09 '13 at 04:08
  • @Luigi : print(String) is more specific method in the above case . I have raised a similar question earlier :http://stackoverflow.com/questions/9361639/java-method-overloading-and-choosing-the-most-specific-type . I don't understand where is the ambiguity in choosing a more specific method here ? – AllTooSir Feb 09 '13 at 04:18
3

It's because System.out.println() expects something with a type. null doesn't have a type, and therefore it can't be output on it's own. This is shown by:

Doesn't work:

 System.out.println(null);

Works:

 System.out.println((String)null);
 System.out.println((char[])null);
 System.out.println((Object)null);

It's the compiler type-checking the parameters of the method call.

Stephen
  • 2,365
  • 17
  • 21
2

Thank you all for your answers . From your inputs , I compiled the answer myself . It seems the call System.out.print(null) is ambiguous to compiler because print(null) here will find the two best specific matches i.e. print(String) and print(char[]) . So compiler is unable to determine which method to call here .
Small example will be :

private void methodCall(String str) {
}

private void methodCall(char[] ch){
}

Now this code becomes ambigious : methodCall(null) .

AllTooSir
  • 48,828
  • 16
  • 130
  • 164