Any,AnyVal,AnyRef,Object之间的关系是什么?在Java代码中如何映射?

我通常最终会尝试每个组合,直到它编译。 有人可以解释我应该在哪里使用?

在一个方面,我会不同意克里斯的 回答 。 AnyAnyRefAnyVal都是类。 但是由于JVM的内在限制,它们不会以字节码forms出现。

这是因为并不是所有的Java都是一个对象。 除了对象之外,还有基元。 Java中的所有对象都是java.lang.Object后代,但是原语被分开设置,目前*不能被程序员扩展。 还要注意,原语有“操作符”,而不是方法。

另一方面,在斯卡拉,一切都是一个对象,所有对象都属于一个类,它们通过方法进行交互。 生成的JVM字节码并不能反映这一点,但是这并没有使它们变得更小,就像Java具有generics一样,尽pipe字节码没有它们。

所以,在Scala中,所有的对象都是Any后裔,包括Java认为的对象和Java认为的基元。 在Java中没有相同的东西,因为没有这种统一。

所有在Java中被认为是原始的东西都是Scala中的AnyVal后裔。 在Scala 2.10.0之前, AnyVal被封了,程序员无法扩展它。 看看.Net上的Scala会发生什么,应该很有趣,因为互操作性本身就要求Scala至less能够识别用户定义的“原语”。

还扩展AnyAnyRef ,它等同于java.lang.Object (无论如何在JVM上)。

直到Scala 2.9.x,用户不能扩展AnyAnyVal ,也不能从Java引用它们,但是在Scala中还有其他用处。 具体而言,键入签名:

 def f(x: AnyVal) = println(x) def g(x: AnyRef) = println(x) def h(x: Any) = println(x) 

从class级层次上来看,每种方法都应该是明显的。 值得注意的是, fh会自动装箱,但g不会。 这与Java所做的有点相反,因为fh不能被指定, g (用java.lang.Object定义)会导致自动装箱。

从Scala 2.10.0开始,用户可以使用以下语义扩展AnyValAny

  • 如果一个类扩展了AnyVal ,那么在某些情况下堆中将不会创build任何实例。 这意味着这个类的字段(在2.10.0上只允许一个字段 – 不pipe这个字段是否将被改变)仍然保留在堆栈上,无论它们是原语还是对其他对象的引用。 这允许扩展方法没有实例化成本。

  • 如果一个特征扩展了Any ,那么它可以用于扩展AnyRef类和扩展AnyRef类。

PS:在我看来,Java很可能遵循C#来允许“struct”原语,也许typedef作为并行而不诉诸于它们,这很难以很好的性能完成。

看过这个? 该页面的文本有一些Java互操作性的评论。 http://www.scala-lang.org/node/128

Scala类层次结构

AnyAnyVal是我认为是scala types系统的一部分, 不是类 (就像Nothingtypes,也不是类)。 您不能在Java代码中显式使用它们。

不pipe怎样,在Java / Scala互操作中,接受Java Object的方法将会得到一个Scala Any / AnyRef

你究竟想要做什么?