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

huy*_*hjl 108 scala

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

Dan*_*ral 121

在一个方面,我不同意克里斯的 回答.该班Any,AnyRefAnyVal 类.但由于JVM的内在局限性,它们不会作为字节码中的类出现.

这是因为并非Java中的所有内容都是对象.除了对象之外,还有原语.Java中的所有对象都是后代java.lang.Object,但原语被分开,目前*,程序员无法扩展.还要注意,基元有"运算符",而不是方法.

另一方面,在Scala中,一切都是对象,所有对象都属于一个类,并且它们通过方法进行交互.生成的JVM字节码并不反映这一点,但这并不会使它们变得那么简单,就像Java具有泛型一样,即使字节码没有它们.

因此,在Scala中,所有对象都是后代Any,包括Java认为对象和Java认为原语的内容.在Java中没有等价物,因为没有这样的统一.

在Java中被认为是原始的所有内容都是AnyValScala的后代.直到Scala 2.10.0 AnyVal被封存,程序员无法扩展它.看看Scala在.Net上会发生什么应该会很有趣,因为互操作性本身要求Scala至少能够识别用户定义的"原语".

还延伸Any就是AnyRef,这相当于java.lang.Object(在JVM上在任何速率).

截至斯卡拉2.9.x,用户不能延长AnyAnyVal,也不是从Java引用它们,但,他们可以在Scala中被投入其他用途.具体来说,键入签名:

def f(x: AnyVal) = println(x)
def g(x: AnyRef) = println(x)
def h(x: Any) = println(x)
Run Code Online (Sandbox Code Playgroud)

从类层次结构中,每个方法应该是显而易见的.值得注意的是,然而,就是fh意志自动箱,但g不会.这与Java所做的有点相反,f并且h无法指定,并且g(定义为java.lang.Object)会导致自动装箱.

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

  • 如果类扩展AnyVal,在某些条件下不会在堆上为它创建实例.这意味着这个类的字段(在2.10.0上只允许一个字段 - 无论是否会改变还有待观察)将保留在堆栈中,无论它们是基元还是对其他对象的引用.这允许扩展方法没有实例化成本.

  • 如果特征扩展Any,那么它可以与扩展的AnyRef类和扩展的类一起使用AnyVal.

PS:在我看来,Java可能会遵循C#来允许"struct"原语,也许是typedef,因为并行性而不诉诸于它们并不能很好地实现性能.

  • 更新:从Scala 2.9.2开始,`AnyVal`被定义为`密封特征AnyVal扩展Any`.但是在Scala 2.10中,这已经变为`抽象类AnyVal使用NotNull扩展Any,现在可以使用新的值类特性扩展`AnyVal`,例如:`class MyValue(val u:Int)扩展AnyVal`. (2认同)

Mit*_*ins 41

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

Scala类层次结构


oxb*_*kes 5

AnyAnyVal是,我相信,阶的部分类型的系统不阶级作为(在相同的方式Nothing是一种类型的,而不是一个类)。您不能在Java代码中显式使用它们。

但是,在Java / Scala互操作中,接受Java的方法Object将期望使用scala Any/ AnyRef

您实际上在尝试做什么?