scala Any、AnyVal、AnyRef、Object之间有什么关系,在Java代码中使用时如何映射?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2335319/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-22 01:58:13  来源:igfitidea点击:

What are the relationships between Any, AnyVal, AnyRef, Object and how do they map when used in Java code?

scala

提问by huynhjl

I usually end up trying every combination until it compiles. Can somebody explain what I should use where?

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

回答by Daniel C. Sobral

I'll disagree with Chris'sanswerin one regard. The classes Any, AnyRefand AnyValareclasses. But they don't appear as classes in bytecode, because of intrinsic limitations of the JVM.

一方面,我不同意克里斯的回答。类AnyAnyRefAnyVal类。但是由于 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.

这是因为并非 Java 中的所有内容都是对象。除了对象,还有基元。Java 中的所有对象都来自java.lang.Object,但原语是​​分开的,目前*不能由程序员扩展。还要注意原语有“操作符”,而不是方法。

In Scala, on the other hand, everything isan object, all objects belong to a class, and they interact through methods. The JVM bytecode generated does not reflect this, but that doesn't make them any less so, just as Java has generics, even though the bytecode doesn't have them.

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

So, in Scala, all objects are descendant from Any, and that includes both what Java considers objects and what Java considers primitives. There's no equivalent in Java because there is no such unification.

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

Everything that is considered a primitive in Java is descendant from AnyValin Scala. Until Scala 2.10.0, AnyValwas sealed, and programmers were unable to extend it. It should be interesting to see what will happen with Scala on .Net, since interoperability alone calls for Scala to at least recognize user-defined "primitives".

在 Java 中被认为是原始类型的所有东西都来自AnyValScala。直到 Scala 2.10.0,AnyVal被密封,程序员无法扩展它。看看 Scala 在 .Net 上会发生什么应该会很有趣,因为仅互操作性就要求 Scala 至少识别用户定义的“原语”。

Also extending Anyis AnyRef, which is equivalent to java.lang.Object(on the JVM at any rate).

还扩展的AnyAnyRef,这相当于java.lang.Object(无论如何在 JVM 上)。

Up to Scala 2.9.x, a user could not extend Anyor AnyVal, nor reference them from Java, but there wereother uses they could be put to in Scala. Specifically, type signatures:

在 Scala 2.9.x 之前,用户不能扩展Anyor AnyVal,也不能从 Java 引用它们,但是它们可以在 Scala 中进行其他用途。具体来说,类型签名:

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

What each means should be obvious from the class hierarchy. Of note, however, is that fand hwill auto-box, but gwill not. That is a bit the opposite of what Java does, in that fand hcannot be specified, and g(defined with java.lang.Object) would cause auto-boxing.

从类层次结构中,每个的含义应该是显而易见的。值得注意的是,然而,就是fh意志自动箱,但g不会。这是一个有点什么Java那样,在对面f,并h不能指定,g(有定义java.lang.Object)会导致自动装箱。

Starting with Scala 2.10.0, though, the user can extend AnyValor Any, with the following semantics:

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

  • If a class extends AnyVal, no instance will be created for it on the heap under certain conditions. This means the fields of this class (on 2.10.0 only a single field is allowed -- whether that will change remains to be seen) will stay on the stack, whether they are primitives or references to other objects. This allows extension methods without the instantiation cost.

  • If a trait extends Any, then it can be used with both classes that extend AnyRefand classes that extend AnyVal.

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

  • 如果 trait 扩展Any,那么它可以用于扩展的AnyRef类和扩展的类AnyVal

PS: In my own view, Java is likely to follow C# in allowing "struct" primitives, and maybe typedefs, as parallelism without resorting to them is proving difficult to accomplish with good performance.

PS:在我自己看来,Java 可能会跟随 C# 来允许“struct”原语,也可能是 typedef,因为事实证明,不使用它们的并行性很难以良好的性能实现。

回答by Mitch Blevins

Seen this? The text of the page has some java interoperability remarks. http://www.scala-lang.org/node/128

看到了吗?该页面的文本有一些 java 互操作性说明。 http://www.scala-lang.org/node/128

Scala Class Heierarchy

Scala 类层次结构

回答by oxbow_lakes

Anyand AnyValare, I believe, part of the scala type systemand are not classes as such(in the same way that Nothingis a type, not a class). You cannot use them explicitly from within Java code.

Any并且AnyVal,我相信,是 Scala类型系统的一部分,而不是类(与Nothing类型相同,而不是类)。您不能在 Java 代码中显式使用它们。

Howwever, in Java/Scala interoperation, a method which accepts a Java Objectwill expect a scala Any/ AnyRef.

但是,在 Java/Scala 互操作中,接受 Java 的方法Object将需要 scala Any/ AnyRef

What are you actually attempting to do?

你究竟想做什么?