Why does the Scala compiler prefer to infer an argument of value null as Array[Char] instead of Object?
Consider these methods from java.lang.String
/**
* Returns the string representation of the <code>Object</code> argument.
*
* @param obj an <code>Object</code>.
* @return if the argument is <code>null</code>, then a string equal to
* <code>"null"</code>; otherwise, the value of
* <code>obj.toString()</code> is returned.
* @see java.lang.Object#toString()
*/
public static String valueOf(Object obj) {
return (obj == null) ? "null" : obj.toString();
}
/**
* Returns the string representation of the <code>char</code> array
* argument. The contents of the character array are copied; subsequent
* modification of the character array does not affect the newly
* created string.
*
* @param data a <code>char</code> array.
* @return a newly allocated string representing the same sequence of
* characters contained in the character array argument.
*/
public static String valueOf(char data[]) 开发者_开发知识库{
return new String(data);
}
and this Scala code
val result = String.valueOf(null)
which results in
String.valueOf(null)
java.lang.NullPointerException
at java.lang.String.<init>(String.java:193)
at java.lang.String.valueOf(String.java:2852)
It works if you annotate null
with any other type except Array[Char]
.
Why does the Scala compiler seem to prefer Array[Char]
to Object
considering that Array
is effectively final and can't be overridden and is invariant in its element type (so the chance that this usage is intended is quite small)?
Array[Char]
is preferred to Object
because it's more specific. If something can be converted to types X or Y, and there's a conversion from X to Y, then X is more specific than Y... and X is effectively preferred over Y when it comes to overloads.
At least, that's assuming Scala is like Java in terms of overload resolution, which I strongly expect it is.
It should be easy to avoid though - just cast the null reference to Object
, to make the overload taking Array[Char]
non-applicable.
EDIT: Okay, having looked at the Scala language specification briefly it's a little more complicated than that, but I believe the basic premise is the same. See p97 in the previous link for all the gory details.
精彩评论