Scala在外部项目中密封了类子类

时间:2014-04-29 05:47:48

标签: java scala jvm

引用Scala的文档:

  

密封类不能直接继承,除非继承模板在与继承类相同的源文件中定义。但是,密封类的子类可以在任何地方继承。

如果我在项目中创建了密封类的层次结构,那就很好了,例如:

sealed abstract class Base {}
sealed class Derived extends Base {}

但是如果我编译项目并在Maven中将其分发为JAR,那该怎么办呢。

如果我在类路径上具有该JAR的第二个项目中编写Java类,该怎么办?

public class Breaker extends Derived {}

它会编译,也就是说这个宪法仍然有效吗?如果我在Scala中写Breaker怎么办?

如果密封在abouve情况下有效,它是如何实现的?

2 个答案:

答案 0 :(得分:4)

Java没有sealed模板的概念,因此Java编译器根本不可能强制执行sealed约束,因为它甚至不知道它们存在。

这不是sealed特有的,甚至不是特定于Scala / Java的。如果两种语言都相互了解,那么这样的事情就会起作用(即Scala编译器需要知道可以想象用于与之互操作的每种编程语言,包括那些甚至还不存在的,反之亦然,每个编译器和解释器用于可以想象地用于与Scala互操作的语言需要知道Scala,甚至是在Scala存在之前编写的编译器,并且他们可以就一种在彼此之间传达这些语义的方法。

当然,让所有语言都知道所有其他语言是O(n²)并且不能扩展,显然语言知道不存在的语言是不可能的。因此,我们所做的是定义一种所有语言都知道的共同语言。在Unix上,这是C结构+ C函数调用,在CLI上,它是CIL字节代码,在Java平台上,是JVM字节代码。

这意味着Scala和Java可以通过绕过JVM字节代码相互通信,但显然它们只能传递可以用JVM字节代码表示的语义。 sealed不是其中之一。

Scala使用注释在字节代码中编码sealed,但Java不理解该注释,即使它已经完成,它实际上并不干净地映射到Java中的任何概念! (与简洁地映射到完全抽象的Scala特征的Java接口不同)。

答案 1 :(得分:1)

给定一个空的sealed类和一个空的普通类,javap转储的差值在RuntimeVisibleAnnotations的值,所以我认为Scala编译器使用Java Annotations来区分sealed个班级。 如果您想进一步调查:

因此,只要涉及Scala编译器,就应该与分发方法无关。

顺便说一下,派生类的javap转储不会改变。