Я не могу отказаться от пакета-частного класса в Scala?
Извините за запоминающийся заголовок.; -)
Я хочу создать класс private-private с методом private-package в Scala, поэтому мой класс выглядит примерно так:
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
}
Однако, если я использую 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);
...
}
Это означает, что хотя компилятор Scala может уважать ограничения доступа, я все равно мог бы вызвать этот класс из любого Java-кода, что является явным нарушением инкапсуляции.
Я что-то упустил?
Есть ли способ сделать эту работу по назначению?
Ответы
Ответ 1
В дополнение к ответу @Régis, компилятор причины Scala не делает класс package-private, потому что по правилам Scala он может быть доступен из других пакетов: а именно подпакеты net.java.truevfs.ext.pace
. Например.
package net.java.truevfs.ext.pace.subpackage
import net.java.truevfs.ext.pace.AspectController
class Subclass extends AspectController { ... }
является законным в Scala, но в Java-классах из net.java.truevfs.ext.pace.subpackage
не удается получить доступ к классам private-private из net.java.truevfs.ext.pace
.
Ответ 2
Вам ничего не хватает.
Многие из ограничителей доступа в scala не имеют эквивалента в java или на уровне jvm. Дополнительная информация, очевидно, находится прямо в файле .class, но есть как пользовательские аннотации, которые интерпретирует только компилятор scala.
Объектная модель scala может быть только частично сопоставлена с объектной моделью jvm, и компилятор java будет видеть эту частичную модель.
Я бы сказал, что матч довольно близок, а компилятор scala отлично работает в Java-совместимости, но ничего не замечает.
Ответ 3
Не совсем правильный ответ 100%...
Вы можете создать объект пакета, если я хочу сделать некоторые причудливые вещи там с частным классом. Объект пакета доступен как любой другой пакет.
Класс MyClass является закрытым пакетом для этого объекта пакета.
Тем не менее, он не является приватным.
package object com.jasongoodwin.foo {
private class MyClass
class AnotherClass {
val myClass = new MyClass
}
}