4

I am using Java 8 and facing some weird error.

The compiler gives the following error:

error: reference to [method] is ambiguous

Here's my code

StringBuilder sb = new StringBuilder();
Stack<Integer> st = new Stack<>();
st.push(123);

sb.append(st.size() > 0 ? st.pop() : 0);

After some searching, I found out that Java convert the ternary operator ? Integer:int to int. Also, overloading resolution prefers append(int i) over append(Object o) (unboxing).

So as I understand, the code should not cause any errors.

  1. type of ternary operator must be int, not Integer
  2. Even though the result is Integer, append(int i) should be invoked due to overloading resolution

Hence, there's no reason to cause ambiguity

This is weird and Only occurs with Java 8 (Not 11, 17 - I've tried)

And an even weirder thing is that this code works

sb.append(st.size() <= 0 ? 0 : st.pop());

Can anyone explain why? Or let me know is there anything I missed

I've tried to find problems at how ternary operator and overloading resolution works, but as I investigated, there's no reason to cause error.

2
  • Given that it doen’t happen in later versions, I would write this off as a bug that's been fixed. Probably, the compiler maintains a choice of int or Integer for the ternary, and can’t choose between append(int) and append(Object). If your problem is that you need to compile it in Java 8, I expect that it works if you cast the ternary with either (int) or (Integer). Commented Mar 28 at 7:18
  • Why are you writing code like this? Even if the compiler figures out what it means, it leaves me and other readers in doubt. That’s bad. Insert a cast or explicit unboxing or boxing to make your intension crystal clear since no one knows the entire JLS by heart. Commented Mar 28 at 9:18

1 Answer 1

6

This is just a compiler bug in Java 8. This is the relevant bug report: JDK-8064464. This was not an issue in Java 7, and is fixed in Java 9.

You are absolutely correct that the type of the ternary operator expression is int. This is a numeric conditional expression as defined by the JLS. Therefore overload resolution should have found append(int) during phase 1 (strict invocation), and does not continue onto phase 2 (loose invocation).

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.