开发者

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜