Answers:
我会在一个方面不同意克里斯的 回答。该班Any
,AnyRef
和AnyVal
是类。但是由于JVM的固有限制,它们不会在字节码中显示为类。
这是由于Java中的并非所有对象都是对象而产生的。除了对象之外,还有其他原语。Java中的所有对象都是的后代java.lang.Object
,但原语是分开设置的,并且当前*是不能由程序员扩展的。还请注意,原语具有“运算符”,而不具有方法。
另一方面,在Scala中,一切都是对象,所有对象都属于一个类,并且它们通过方法进行交互。生成的JVM字节码不能反映出这一点,但这并不能使它们变得如此,就像Java具有泛型一样,即使字节码没有泛型也是如此。
因此,在Scala中,所有对象都是的后代Any
,并且包括Java认为的对象和Java认为的原语。Java中没有等效项,因为没有这样的统一。
Java中所有被认为是原始的东西都是AnyVal
Scala的后代。在AnyVal
密封Scala 2.10.0之前,程序员无法对其进行扩展。有趣的是,在.Net上看到Scala会发生什么,因为互操作性仅要求Scala至少识别用户定义的“基元”。
还延伸Any
是AnyRef
,这相当于java.lang.Object
(在JVM上在任何速率)。
截至斯卡拉2.9.x,用户不能延长Any
或AnyVal
,也不是从Java引用它们,但人,他们可以在Scala中被投入其他用途。具体来说,类型签名:
def f(x: AnyVal) = println(x)
def g(x: AnyRef) = println(x)
def h(x: Any) = println(x)
从类层次结构中,每种含义应该是显而易见的。值得注意的是,然而,就是f
和h
意志自动箱,但g
不会。这是一个有点什么Java那样,在对面f
,并h
不能指定,g
(有定义java.lang.Object
)会导致自动装箱。
但是,从Scala 2.10.0开始,用户可以使用以下语义扩展AnyVal
或Any
:
如果类扩展AnyVal
,则在某些情况下不会在堆上为其创建实例。这意味着此类的字段(在2.10.0上仅允许单个字段-是否会更改仍待观察)将保留在堆栈中,无论它们是原语还是对其他对象的引用。这允许扩展方法而无需实例化成本。
如果特征扩展Any
,则可以将其与扩展AnyRef
类和扩展类一起使用AnyVal
。
PS:在我看来,Java可能会遵循C#来允许“结构”原语,甚至可能是typedef,因为事实证明,不求助于它们的并行性很难以良好的性能实现。
看到这个了吗?该页面的文本具有一些Java互操作性说明。 http://www.scala-lang.org/node/128
Any
和AnyVal
是,我相信,阶的部分类型的系统和不阶级作为(在相同的方式Nothing
是一种类型的,而不是一个类)。您不能在Java代码中显式使用它们。
但是,在Java / Scala互操作中,接受Java的方法Object
将期望使用scala Any
/ AnyRef
。
您实际上在尝试做什么?
AnyRef
只是提醒我,这对我来说仍然很神秘。
AnyVal
定义为sealed trait AnyVal extends Any
。但是在Scala 2.10中,它已更改为abstract class AnyVal extends Any with NotNull
,现在可以AnyVal
使用新的值类功能进行扩展,例如:class MyValue(val u: Int) extends AnyVal
。