Ответ 1
Доступ к внутренним классам с помощью $
java.nio.channels.FileChannel$MapMode/READ_ONLY
В основном, что мне нужно сделать, это
FileChannel.MapMode.READ_ONLY
Я попытался сделать очевидный
(.. FileChannel MapMode READ_ONLY)
но в результате возникает исключение
java.lang.NoSuchFieldException: MapMode
даже обозначение /
, указанное как для статических полей доступа в документации interop, дает то же исключение
(. (FileChannel/MapMode) READ_ONLY)
Доступ к внутренним классам с помощью $
java.nio.channels.FileChannel$MapMode/READ_ONLY
Синтаксис (FileChannel/MapMode)
является упрощением и предназначен только для статических полей и методов (для полей вы можете даже опустить круглые скобки)! Также формы .
и ..
предназначены для полей/методов, но НЕ для вложенных/внутренних классов!
Для JVM внутренний класс Outer.Inner
- это просто класс с именем Outer$Inner
(а компилятор создает для него файл Outer$Inner.class
). Компилятор Java позволяет ссылаться на него с помощью Outer.Inner
. Вы также можете определить не внутренний класс с именем Outer$Inner
, к которому компилятор позволяет вам ссылаться как Outer$Inner
. Однако вы не можете определить оба в то же время, поскольку оба будут иметь имена классов Outer$Inner
(и .class
файлов с именем Outer$Inner.class
, так что это будет двойное имя класса!)
При использовании отражения - например, с Class.forName()
- (как правило, чтобы ввести некоторую динамичность) вы не можете опустить имя пакета импортированного класса, и вы должны использовать имя реального класса с знаком $
вместо точки.
Вероятно, для своей динамической природы Clojure использует тот же подход, поэтому вам нужно использовать форму my.package.Outer$Inner
, если класс находится в my.package
- даже если вы уже импортировали внешний класс! Чтобы избежать имени пакета, вы можете явно импортировать внутренний класс my.package.Outer$Inner
, а затем ссылаться на него как Outer$Inner
(его настоящее имя класса!), Но вы не уменьшите это до Inner
, просто импортировав его:
Inner
не имеет смысла для JVM, только Java-Compiler предлагает вам этот ярлык из контекста времени компиляции (который НЕ доступен для JVM и методов, таких как Class.forName
во время выполнения!)... OK, в Clojure вы, конечно, всегда можете определить: (def Inner Outer$Inner)
... или (def Tom Outer$Inner)
или (def Harry Outer$Inner)
или что-то еще... если вам это нравится.