Scala继承层次结构图:
Scala for the Impatient中的上图显示了所有Java类都是 AnyRef 类的子类 .
AnyRef
图8-1显示了Scala类的继承层次结构 . 与Java中的基元类型对应的类以及类型Unit扩展AnyVal . 所有其他类都是AnyRef类的子类,它是Java或.NET虚拟机中Object类的同义词 . AnyVal和AnyRef都扩展了Any类,即层次结构的根 .
如何在不改变Java类的情况下实现这一目标?它是在字节码级别处理的吗?
免责声明:我绝不是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 )
java.lang.Object
Object
我打赌你不会在任何Scala运行时JAR库中找到 AnyRef.class 条目,这意味着对于JVM,类似 AnyRef 的类不存在 .
AnyRef.class
这通常会让初学者感到困惑 . 最近有一个very similar question on Software Engineering.SE . 简单的答案是:魔术!
对真的 .
Scala编译器不必遵守Scala语言的规则 . 从某种意义上说,这是Scala语言的规则!它必须实现和实施它们,但它不必遵循Java语言的规则 .
因此,它的工作方式非常简单:每当某个Scala程序执行某些依赖于 java.lang.String 的行为时,就好像它是 scala.AnyRef 的子类一样,它生成的行为就好像 java.lang.String 是 scala.AnyRef 的子类 .
java.lang.String
scala.AnyRef
而已 .
您还可以询问Scala如何创建Java原语对象,这些对象是 scala.AnyVal 的子类的类的实例 . 或者,您可以问一下,当您在两个编辑器窗口中打开两个文件的源代码时,程序员如何看到两个类的私有实现,即使该语言表示您无法从外部看到私有实现 .
scala.AnyVal
原因总是一样的:因为你坐在语言之外,语言规则不适用于你 .
从另一个方向,人们经常会问为什么他们可以从Java子类化 sealed 类或调用声明为 private[this] 的方法 . 原因是一样的:因为Java编译器没有规则 . 它甚至不知道Scala的规则 .
sealed
private[this]
2 回答
免责声明:我绝不是Scala专家,但拥有20年的Java经验,包括JVM .
我的解释是那句话
(强调我的)完美地解释了它 .
对于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
的类不存在 .这通常会让初学者感到困惑 . 最近有一个very similar question on Software Engineering.SE . 简单的答案是:魔术!
对真的 .
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的规则 .