Consider this Minimal, Reproducible Example :
interface Code {
static void main(String[] args) {
symbol(
String.valueOf(
true ? 'a' :
true ? 'b' :
true ? 'c' :
fail()
)
);
}
private static void symbol(String symbol) {
System.out.println(symbol);
}
private static <R> R fail() {
throw null;
}
}
(Being near minimal, true
is a stand in for a useful boolean expression. We can ignore beyond the first ? :
(in the real code, there are lots).)
This 'obviously' gives the error.
4: reference to valueOf is ambiguous
both method valueOf(java.lang.Object) in java.lang.String and method valueOf(char) in java.lang.String match
Okay let's fix it. It's the String.valueOf(Object)
overload I want - I might later want to add:
true ? "sss" :
(In fact I did have something similar earlier, but have now removed the feature.)
String.valueOf((Object)(
true ? 'a' :
fail()
))
This gives the warning:
4: redundant cast to java.lang.Object
Is this a bug in the compiler warning or error, and how do I fix it so the code is reasonable and there are no warnings or errors?
(Edits: I've change the MRE slightly. throws Throwable
was from a template. The real code does use literal chars* and String.valueOf
Elsewhere it uses the String.valueOf(char)
overload, so toString()
is problematic (oh Java!). The code avoids global state, such as System.out
, and symbol
and fail
are in different classes. The "switch" is of a non-enumerable type. fail
is a companion to an assert-like method, so that's why it throws an (unchecked non-null) exception internally.
How I actually fixed it was, unrelatedly, I rearranged code so there were some literal strings in there too. Otherwise, I would have used the pointless Object.class.cast
equivalent of (Object)
. What I really want to know is: wtf?
*Actually the real real code goes through a lexer for a different language that doesn't distinguish between literal char, string, various numbers, boolean, enums, etc. Why would it?)
true ? 'a' : fail()
equivalent to just'a'
? What is the purpose of this construct? – Dipetaloustrue
is just to make the example code simple. The real code has lines liketype == SymbolToken.assign ? '=' :
. – Poodle'a'
to"a"
removes the warning, but I assume you know that already. Please share more of your mental model of what you're trying to achieve. – Dipetalous"a
"` is converted to'a'
because"abc"
is indistinguishable from'abc
and so the preprocessor (which is just a stop gap) guesses that a single letter is achar
constant. In any case, in an equivalent situation thechar
could be return by some random function. – Poodlechar
toObject
. Could this be an XY Problem? – Dipetalousmain
with a method parameterised with the values and added several? :
s. – Poodle