为什么 Scala 编译器更喜欢将 null 值的参数推断为 Array[Char] 而不是 Object?
考虑 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)
如果您使用除 Array[Char]null
,它就会起作用 代码>.
为什么 Scala 编译器似乎更喜欢 Array[Char]
而不是 Object
,因为 Array
实际上是最终的,不能被覆盖并且是不变的在它的元素类型中(所以这种用法的可能性很小)?
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)?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
Array[Char]
优于Object
,因为它更具体。如果某些东西可以转换为 X 或 Y 类型,并且存在从 X 到 Y 的转换,那么 X 比 Y 更具体......并且在重载时 X 实际上比 Y 更受青睐。至少,这是假设 Scala 在重载解析方面与 Java 类似,我强烈希望它是这样。
不过,这应该很容易避免 - 只需将 null 引用强制转换为
Object
即可,以使Array[Char]
的重载不适用。编辑:好的,简单地查看了 Scala 语言规范 比这稍微复杂一些,但我相信基本前提是相同的。请参阅上一个链接中的 p97 了解所有血淋淋的细节。
Array[Char]
is preferred toObject
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 takingArray[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.