首页 文章

如何在Scala中创建AnyRef的现有Java类子类?

提问于
浏览
4

Scala继承层次结构图:

Scala for the Impatient中的上图显示了所有Java类都是 AnyRef 类的子类 .

图8-1显示了Scala类的继承层次结构 . 与Java中的基元类型对应的类以及类型Unit扩展AnyVal . 所有其他类都是AnyRef类的子类,它是Java或.NET虚拟机中Object类的同义词 . AnyVal和AnyRef都扩展了Any类,即层次结构的根 .

如何在不改变Java类的情况下实现这一目标?它是在字节码级别处理的吗?

2 回答

  • 4

    免责声明:我绝不是Scala专家,但拥有20年的Java经验,包括JVM .

    我的解释是那句话

    所有其他类都是AnyRef类的子类,它是Java或.NET虚拟机中Object类的同义词 .

    (强调我的)完美地解释了它 .

    对于JVM,没有 AnyRef 类 . 该文本将 AnyRef 称为同义词,而JVM没有这样的概念 . 因此,可能Scala编译器将 AnyRef 的出现替换为 java.lang.Object . 当然,所有Java类都是 java.lang.Object 的子类,它只是在Scala编译器中得到一个新名称,从而使它们都继承自 AnyRef (a.k.a . Object

    我打赌你不会在任何Scala运行时JAR库中找到 AnyRef.class 条目,这意味着对于JVM,类似 AnyRef 的类不存在 .

  • 6

    这通常会让初学者感到困惑 . 最近有一个very similar question on Software Engineering.SE . 简单的答案是:魔术!

    对真的 .

    Scala编译器不必遵守Scala语言的规则 . 从某种意义上说,这是Scala语言的规则!它必须实现和实施它们,但它不必遵循Java语言的规则 .

    因此,它的工作方式非常简单:每当某个Scala程序执行某些依赖于 java.lang.String 的行为时,就好像它是 scala.AnyRef 的子类一样,它生成的行为就好像 java.lang.Stringscala.AnyRef 的子类 .

    而已 .

    您还可以询问Scala如何创建Java原语对象,这些对象是 scala.AnyVal 的子类的类的实例 . 或者,您可以问一下,当您在两个编辑器窗口中打开两个文件的源代码时,程序员如何看到两个类的私有实现,即使该语言表示您无法从外部看到私有实现 .

    原因总是一样的:因为你坐在语言之外,语言规则不适用于你 .

    从另一个方向,人们经常会问为什么他们可以从Java子类化 sealed 类或调用声明为 private[this] 的方法 . 原因是一样的:因为Java编译器没有规则 . 它甚至不知道Scala的规则 .

相关问题