23

I am using the code:

System.out.println(null);

It is showing the error:

The method println(char[]) is ambiguous for the type PrintStream

Why doesn't null represent Object?

Kannan Thangadurai
  • 1,117
  • 2
  • 17
  • 36
  • 2
    `System.out.println((Object)null);` – Yassin Hajaj Mar 31 '16 at 06:02
  • 1
    Possible duplicate of [unable to pass null to execute(); method of AsyncTask in android 4.0](http://stackoverflow.com/questions/10679739/unable-to-pass-null-to-execute-method-of-asynctask-in-android-4-0) – Raedwald Apr 04 '16 at 05:47
  • 1
    See also http://stackoverflow.com/questions/13033037/how-is-an-overloaded-method-chosen-when-a-parameter-is-the-literal-null-value – Raedwald Apr 04 '16 at 05:50

2 Answers2

27

There are 3 println methods in PrintStream that accept a reference type - println(char x[]), println(String x), println(Object x).

When you pass null, all 3 are applicable. The method overloading rules prefer the method with the most specific argument types, so println(Object x) is not chosen.

Then the compiler can't choose between the first two - println(char x[]) & println(String x) - since String is not more specific than char[] and vice versa.

If you want a specific method to be chosen, cast the null to the required type.

For example :

System.out.println((String)null);
Eran
  • 387,369
  • 54
  • 702
  • 768
  • 1
    I know and understand this concept. But for sake of the completeness of the answer, does the JLS somewhere specify why, for example, `char[]` and `String` are equally specific? After all, `char` is a primitive and `String` is an object. – Magnilex Mar 31 '16 at 06:11
  • 12
    @Magnilex char is a primitive, but char[] is an object. char[] is not a sub-class of String and String is not a sub-class of char[]. Therefore neither one of the two is more specific. – Eran Mar 31 '16 at 06:14
  • 4
    @KannanThangadurai note that you can write `char x[]` as `char[] x` - many (e.g. [Google's style guide](https://google.github.io/styleguide/javaguide.html#s4.8.3.2-array-declarations)) prefer the latter form because the type of `x` is `char[]`, not `char`. Keeping the type together makes it easier to read. – Andy Turner Mar 31 '16 at 07:49
8

If you call System.println(null) there are multiple candidate methods (with char [], String and Object argument) and the compiler can't decide which one to take.

Fix
Add an explicit cast to null.

System.out.println((Object)null);

Or use null object pattern.


Why does't null represent Object?

From JLS 4.1 The Kinds of Types and Values

There is also a special null type, the type of the expression null, which has no name.
Because the null type has no name, it is impossible to declare a variable of the null type or to cast to the null type.
The null reference is the only possible value of an expression of null type. The null reference can always be cast to any reference type.
The null reference can always be assigned or cast to any reference type

In practice, the programmer can ignore the null type and just pretend that null is merely a special literal that can be of any reference type

So the type of null is not Object, though it can be converted to (read-as assigned to) an Object.

Gyapti Jain
  • 4,056
  • 20
  • 40