【问题标题】:trying to understand "final abstract class Int private extends AnyVal in Scala试图理解“最终抽象类 Int private 在 Scala 中扩展 AnyVal
【发布时间】:2012-09-05 21:19:35
【问题描述】:

来自 Java Land,我一直在尝试自学 Scala。最近我在玩Int 数据类型,我决定查找Int 类here 的API。

让我感到困惑的是Int 的类定义,即abstract final

如果我在问这个问题之前没有阅读 Scala 中 abstractfinal 的含义,我深表歉意,但我很好奇,所以我立即输入了这篇文章。

所以我想了解的是: Scala 中abstractfinalextends 的语义是否不同? 同样,据我所知,在 Java 中,不能同时拥有 abstractfinal。 那么我该如何解读final abstract class Int private extends AnyVal呢?

【问题讨论】:

  • 不,它们不是,至少基本上(你仍然不能实例化抽象,你不能继承/覆盖 final)。 AFAIK,这样做的原因是前一段时间 Int 和其他 AnyVal 类型只是一个存根,然后由编译器在编译时重写。他们不是因为this commit
  • 哦,这是有用的信息。感谢您向我指出这一点

标签: scala


【解决方案1】:

正如 om-nom-nom 在评论中指出的那样,abstract 禁止实例化 (new Int),而 final 禁止子类化 (new Int { ... })。

原因是scala.Int直接用Java虚拟机的原始整数类型表示;其他类似的类型是ByteShortCharLongFloatDoubleBoolean因为它们是运行时的原始类型(表现出比所谓的装箱类型更好的性能)并且 JVM 不允许添加新的原始类型,因此没有合法的方式来扩展这些类型。除了提供文字 (val i: Int = 33) 之外,没有其他方法可以实例化它们。

Scala 拥有这些类型来创建一个统一的对象系统,其中原始类型和“对象”之间没有逻辑上的区别。然而,顶部有一个层次区别,即AnyRef(对应于java.lang.Object)和AnyVal(对应于那些原始类型;并添加了Scala的新类型Unit)。

Tour of Scala: Unified Types 提供了有关统一类型系统的更多信息

【讨论】:

  • 我必须注意,还有accepted SIP 将释放非默认行为的未装箱原语的使用。
  • P.S.尽管所有 JVM 原语都由 AnyVal 的子类型表示,但反过来并不成立(Unit 已经提到过)。在 Scala 2.10 中,可以扩展 AnyVal,创建所谓的 Value-Classes,用于实现新的数字类,受益于编译器优化(例如内联)。
  • 我访问了@om-nom-nom 给我的链接。它说“AnyVal 类型成为源文件,而不是礼貌的编译器虚构。这是什么意思?这是否意味着不再有 Int、Byte 等的直接 JVM 表示,而是我们现在有一种方法来表示它们。对不起如果我不是在问一个聪明的问题。
  • 呃,那是 PaulP 散文中的提交信息... Long.scala——尽管如此,虽然它们定义了接口,但您可以看到它们都没有实际的方法体,因此 IMO 编译器虚构(即编码为 JVM 原语)仍然存在。在这方面没有任何改变(从用户的角度来看)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-01-30
  • 1970-01-01
  • 2013-02-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多