1
System.out.println((true) ? null: null);

Question:

Why I have got

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

and why it is not computed, and null is passed as parameter to println method or in other way, Why expression (true) ? null: null is treated as char[].

Edit: IDE Used Eclipse.

Vishrant
  • 15,456
  • 11
  • 71
  • 120

5 Answers5

3

You aren't specifying the error correctly.

Look at the overloads for PrintStream.println(). You'll notice that the only reference types are char[], String and Object.

Netbeans gives me the error

Exception in thread "main" java.lang.RuntimeException: Uncompilable source code - reference to println is ambiguous both method println(char[]) in java.io.PrintStream and method println(java.lang.String) in java.io.PrintStream match

Which is just the way we expected it to be: it can't choose between either of them since both are equally valid.

The reason why it does not mention the Object overload can be found in the smallprint in the JLS at chapter $15.12.2. Compile-Time Step 2: Determine Method Signature:

For example, declaring m(Object...) in a class which already declares m(Object) causes m(Object) to no longer be chosen for some invocation expressions (such as m(null)), as m(Object[]) is more specific.

You can find this in the explanation of the first phase.

Jeroen Vannevel
  • 43,651
  • 22
  • 107
  • 170
1

When a method has overloaded versions like println(), println(char[] x), println(String x) etc then compiler can't decide which method to choose for "null" as input. So, it throws a compile time exception saying its ambiguous.

Here, given expression "(true) ? null: null" results in "null" output which is passed as input to println method as "System.out.println(null)" which gives mentioned exception.

crashstorm
  • 130
  • 5
  • even `System.out.println(true ? null: new Object());` results `null` but is not ambiguous. – Vishrant Aug 11 '14 at 15:32
  • 1
    In case of "true ? null: null" both the arguments are null for this ternary operation, compiler can't decide which method to choose from because all methods are equally suitable. But in case of "true ? null: new Object()", compiler can decide the possible outcome of the operation as Object so it chooses println(Object x) method. Similarly, in case of "true ? null: new String()", the method chosen by compiler is println(String x). So, based on the possible outcome of the expression, compiler can decide which method to choose. – crashstorm Aug 11 '14 at 15:59
0

I think this is a question of Java method dispatching.

This question has (kinda) already been asked here Java method dispatch with null argument

Here too Method Overloading for null argument

I think this is the relevant bit in the Oracle docs:

"There may be more than one such method, in which case the most specific one is chosen. The descriptor (signature plus return type) of the most specific method is one used at run time to perform the method dispatch."

Community
  • 1
  • 1
Ramsay Domloge
  • 695
  • 3
  • 11
  • While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. – Brian Aug 11 '14 at 16:02
  • Thanks for your feedback. Update includes quote from the linked page which answers question. – Ramsay Domloge Aug 11 '14 at 16:04
0

I think Sotirios is correct although I am not sure it explains why the compiler calls the invocation ambiguous.

The problem is that System.out is a PrintStream, and that has several methods accepting a reference type, including one for char[], Object, and String. Your invocation on the null type could be any of them.

I actually get a slightly different error from javac that points out at least two methods that match.

Sean Owen
  • 66,182
  • 23
  • 141
  • 173
0

The available overloaded versions of println are as follows:

public void println();

public void println(char x);

public void println(boolean x);

public void println(char[] x);

public void println(int x);

public void println(double x);

public void println(long x);

public void println(float x);

public void println(String X);

public void println(Object x) ;

The compiler not able to link this System.out.println(null); to any above overloaded versions as all corresponds to the null except the very Ist one. And therefore, the error ambiguous for the type PrintStream is happened to be occurred.

ketan
  • 19,129
  • 42
  • 60
  • 98