Подтвердить что ты не робот

Я не могу отказаться от пакета-частного класса в 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-кода, что является явным нарушением инкапсуляции.

Я что-то упустил? Есть ли способ сделать эту работу по назначению?

4b9b3361

Ответ 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
  }
}