我会不同意Chris's answer一方面。课程Any
, AnyRef
and AnyVal
are类。但由于 JVM 的内在限制,它们在字节码中不会显示为类。
This arises out of the fact that not everything in Java is an object. In addition to objects, there are primitives. All objects in Java are descendant from java.lang.Object
, but primitives are set apart and, presently*, not extensible by a programmer. Note also that primitives have "operators", not methods.
另一方面,在 Scala 中,一切is一个对象,所有对象都属于一个类,它们通过方法进行交互。生成的 JVM 字节码并没有反映这一点,但这并没有让它们变得不那么重要,就像 Java 有泛型一样,尽管字节码没有泛型。
所以,在 Scala 中,所有对象都是来自Any
,其中包括 Java 所认为的对象和 Java 所认为的原语。 Java 中没有对应的东西,因为没有这样的统一。
Java 中所有被认为是原语的东西都是来自AnyVal
在斯卡拉。直到 Scala 2.10.0,AnyVal
被密封了,程序员无法扩展它。看看 Scala 在 .Net 上会发生什么应该很有趣,因为仅互操作性就要求 Scala 至少识别用户定义的“基元”。
还延伸Any
is AnyRef
,这相当于java.lang.Object
(无论如何在 JVM 上)。
在 Scala 2.9.x 之前,用户无法扩展Any
or AnyVal
,也没有从 Java 引用它们,但是有were它们可以在 Scala 中用于其他用途。具体来说,输入签名:
def f(x: AnyVal) = println(x)
def g(x: AnyRef) = println(x)
def h(x: Any) = println(x)
从类层次结构中,每个含义应该是显而易见的。然而值得注意的是,f
and h
会自动装箱,但是g
将不会。这与 Java 的做法有点相反,因为f
and h
无法指定,并且g
(定义为java.lang.Object
)会导致自动装箱。
不过,从 Scala 2.10.0 开始,用户可以扩展AnyVal
or Any
,具有以下语义:
PS:在我看来,Java 很可能会效仿 C# 来允许“struct”原语,也许还有 typedef,因为事实证明,不诉诸它们的并行性很难以良好的性能实现。