pat*_*rit 13 reflection scala access-modifiers nosuchmethoderror structural-typing
这不能按预期工作(因为我试图run从外部调用包私有Services):
object Services {
class HelloPrinter {
private[Services] def run = "Hello"
}
}
val obj = new Services.HelloPrinter
Run Code Online (Sandbox Code Playgroud)
但是,令人惊讶的是这有效:
val obj: {def run: String} = new Services.HelloPrinter
obj.run
Run Code Online (Sandbox Code Playgroud)
我会说,它是编译器中的一个错误,因为HelloPrinter由于包可见性规则而与结构类型不匹配,所以它根本不应该编译!
这是程序编译但抛出运行时异常(java.lang.NoSuchMethodException)的情况:
class HelloPrinter {
private[HelloPrinter] def run = "Hello"
}
val obj: {def run: String} = new HelloPrinter
obj.run
Run Code Online (Sandbox Code Playgroud)
这是我缺少的语言功能或规则,还是合法的Scala中的错误?
在 JVM 级别上,不存在仅限于周围实例/类型的可见性。在这种情况下,Scala 编译器将生成一个公共方法并在内部处理此可见性。
如果您使用结构类型,编译器将反射性地访问该类型的成员。它不会检查 Scala 特定的可见性标志,而只会检查 Java 字节码中定义的可见性标志。
您没有提到您正在使用哪个版本的 Scala 编译器,但我认为这是您的特定版本中的一个错误。当尝试编译它时,我得到了与 Jasper-M 相同的结果。原因是编译器生成的方法实际上以类型名称为前缀,即HelloPrinter$$run在本例中。将执行以下代码:
val x: { def HelloPrinter$$run: String } = new HelloPrinter
x.run
Run Code Online (Sandbox Code Playgroud)
同样,Scala 编译器只是生成一个公共方法并在内部管理可见性。编译器不检查结构类型的 Scala 内部可见性,这不是一个功能,而是一个错误。
| 归档时间: |
|
| 查看次数: |
190 次 |
| 最近记录: |