为什么Scala编译器更喜欢将值为null的参数推断为Array [Char]而不是Object?

时间:2011-01-15 17:03:40

标签: java scala interop null overloading

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);
}

和此Scala代码

val result = String.valueOf(null)

导致

String.valueOf(null)
java.lang.NullPointerException
  at java.lang.String.<init>(String.java:193)
  at java.lang.String.valueOf(String.java:2852)

如果您使用null以外的任何其他类型注释Array[Char],则此方法有效。

为什么Scala编译器似乎更喜欢Array[Char]Object,因为Array实际上是最终的并且不能被覆盖并且在其元素类型中是不变的(所以有机会这个用法很小)?

1 个答案:

答案 0 :(得分:5)

Array[Char]Object更受欢迎,因为它更具体。如果某些东西可以转换为X或Y类型,并且存在从X Y的转换,那么X比Y更具体...当涉及到重载时,X实际上优于Y.

至少,假设Scala在重载分辨率方面与Java类似,我强烈期望它。

应该很容易避免 - 只需将空引用转换为Object,以使重载Array[Char]不适用。

编辑:好的,看了Scala language specification 简要它比这复杂一点,但我相信基本前提是一样的。有关所有血腥细节的信息,请参见上一个链接中的p97。