对不起,这个引人注目的标题.;-)
我想在Scala中使用package-private方法创建一个包私有类,所以我的类看起来像这样:
package net.java.truevfs.ext.pace
import ...
private[pace] abstract class AspectController(controller: FsController)
extends FsDecoratingController(controller) {
private[pace] def apply[V](operation: => V): V
... // lots of other stuff
}
Run Code Online (Sandbox Code Playgroud)
但是,如果我使用javap来检查Scala编译器有效创建的内容,我会得到这样的结果:
$ javap -classpath target/classes net.java.truevfs.ext.pace.AspectController
Compiled from "AspectController.scala"
public abstract class net.java.truevfs.ext.pace.AspectController extends net.java.truevfs.kernel.spec.FsDecoratingController implements scala.ScalaObject{
public abstract java.lang.Object apply(scala.Function0);
...
}
Run Code Online (Sandbox Code Playgroud)
这意味着尽管Scala编译器可能会尊重访问限制,但我仍然可以从任何Java代码中调用此类,这是一种明显的封装违规.
我错过了什么吗?有没有办法使这项工作按预期进行?
Ale*_*nov 15
除了@Régis的答案之外,Scala编译器没有使类包私有的原因是因为通过Scala规则它可以从其他包访问:即子包net.java.truevfs.ext.pace.例如
package net.java.truevfs.ext.pace.subpackage
import net.java.truevfs.ext.pace.AspectController
class Subclass extends AspectController { ... }
Run Code Online (Sandbox Code Playgroud)
在Scala中是合法的,但在Java类net.java.truevfs.ext.pace.subpackage中无法访问来自的包 - 私有类net.java.truevfs.ext.pace.
你没有遗漏任何东西.scala中的许多访问限制在java和jvm级别都没有等效.附加信息显然在.class文件中,但是作为自定义注释只有scala编译器会解释.scala对象模型只能部分匹配jvm对象模型,而java编译器只能看到这个部分模型.我会说匹配非常接近,scala编译器在java互操作性方面表现非常出色,但不是很完美.
| 归档时间: |
|
| 查看次数: |
3793 次 |
| 最近记录: |