Я определял частные и защищенные методы из классов Scala, но при компиляции в java-байт-код они просто исчезают, и все методы становятся общедоступными! поэтому при вызове из java я могу позвонить любому из них. Правильно, что я говорю? и если да, то с этим в ближайшем будущем изменится с новым компилятором?Интеграция с Java и Scala с частными модификаторами
ответ
Иногда доступ расширяется без какого-либо имени или обфускации.
Здесь можно было бы ожидать реализации, чтобы показать доступ пакета по умолчанию:
scala> :pa
// Entering paste mode (ctrl-D to finish)
package p { class C { private[p] def c = 42 }}
// Exiting paste mode, now interpreting.
scala> :javap p.C
[snip]
public int c();
специальная сбруя приводится здесь для сравнения с шаблоном:
scala> case class C(private val c: Int)
defined class C
scala> :javap -pv C
[snip]
private final int c;
descriptor: I
flags: ACC_PRIVATE, ACC_FINAL
public int c$access$0();
Это не является хорошей идеей, чтобы полагаться на любой такой детали реализации для целей общего взаимодействия. Однако Scala обещает двоичную совместимость в серии релизов, такой как 2.12.x. Все, что скомпилировано с помощью 2.12.1, должно связываться с новым кодом, скомпилированным с помощью 2.12.2.
Я определял частные и защищенные методы из классов Scala, но при компиляции в java-байт-код они просто исчезают, и все методы становятся общедоступными!
Семантика модификатора доступа Scala не сопоставляется с семантикой модификатора доступа JVM. Любой способ их перевода обязательно должен быть приблизительным. Иногда наиболее близким приближением является public
.
Так оно и есть. Просто посмотрите на Scala-native для сравнения, который компилируется в собственный двоичный машинный код: all модификаторы доступа и все типы полностью ушли, потому что просто невозможно представить их в собственном двоичном коде машины. Даже Java не может быть должным образом представлена в байт-коде JVM (например, Java имеет Generics, но JVM не может представить их).
поэтому при вызове из java я могу позвонить любому из них. Правильно, что я говорю?
Да. Когда вы используете Java для взаимодействия с кодом Scala, вы обходите любую проверку, выполняемую компилятором Scala. Об этом нет.
, и если да, то с этим в ближайшем будущем изменится новый компилятор?
Нет. Это потребует изменения спецификации JVM, чтобы языки могли указывать свою собственную семантику модификатора доступа. Я этого не вижу.
Спасибо за ваши комментарии!Вот пример того, что я говорил: класса Person() { частного выполнение четкости() { } защищаемой Защита пешком (мили: Int) { } } В этом случае оба метода (walk и run) становятся общедоступными при использовании класса, скомпилированного (.class) из Java или Scala. Я понимаю, что то же самое происходит с дженериками, они не являются частью виртуальной машины, но лично я вижу, что модификаторы важнее, чем общие, без дженериков, вы даже можете сделать это по-старому. – mingo
Даже «частный» модификатор Java по классам (относится только к вложенным типам) фактически не хранится в обычном поле модификатора доступа. Он хранится в специальном атрибуте, посвященном внутренним классам, поддерживаемом Reflection, тогда как сам JVM не применяет этот уровень доступа «private» ... – Holger
Пожалуйста, запишите код, который вы ищите. – marios