Scala继承层次结构图:
Scala for the Impatient 一书中的上图显示所有Java类都是AnyRef
类的子类。
图8-1显示了Scala类的继承层次结构。与Java中的基元类型对应的类以及类型
Unit
扩展AnyVal
。所有其他类都是AnyRef
类的子类,它是Java或.NET虚拟机中Object
类的同义词。AnyVal
和AnyRef
都扩展了Any
类,即层次结构的根。
如何在不更改Java类的情况下实现这一目标?它是否在字节码级别处理?
答案 0 :(得分:6)
免责声明:我绝不是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
这样的类并不存在。
答案 1 :(得分:4)
这常常让初学者感到困惑。最近有一个very similar question on Software Engineering.SE。简单的答案是:MAGIC!
是的,真的。
Scala编译器不必遵守Scala语言的规则。从某种意义上说,是 Scala语言的规则!它必须实施和执行它们,但它不必遵循它们。而且它肯定不必遵循Java语言的规则。
因此,它的工作方式非常简单:每当某个Scala程序执行某些依赖于java.lang.String
的行为就好像它是scala.AnyRef
的子类时,它会生成一个行为就好像java.lang.String
是scala.AnyRef
的子类。
那就是它。
您还可以询问Scala如何创建Java基元对象,这些对象是作为scala.AnyVal
的子类的类的实例。或者,您可以问一下,当您在两个编辑器窗口中打开两个文件的源代码时,程序员如何看到两个类的私有实现,即使该语言表明您无法从中查看私有实现。外部。
原因总是一样的:因为您在语言之外,语言规则不适用于您。
从另一个方向来看,人们经常会问为什么他们可以从Java继承sealed
类或调用声明为private[this]
的方法。原因也是一样的:因为Java编译器不必使用Scala的规则。它甚至不会知道关于Scala规则的。