Как получить доступ к статическому внутреннему классу Java через взаимодействие Clojure?

java interop clojure

7480 просмотра

2 ответа

В основном, что мне нужно сделать, это

FileChannel.MapMode.READ_ONLY

Я пытался сделать очевидное

(.. FileChannel MapMode READ_ONLY)

но в конечном итоге бросает исключение

java.lang.NoSuchFieldException: MapMode

даже /обозначение, указанное для статических полей доступа в документации взаимодействия, выдает то же исключение

(. (FileChannel/MapMode) READ_ONLY)
Автор: Jakub Arnold Источник Размещён: 12.11.2019 09:13

Ответы (2)


85 плюса

Решение

Вы получаете доступ к внутренним классам с помощью $

java.nio.channels.FileChannel$MapMode/READ_ONLY
Автор: Hamza Yerlikaya Размещён: 21.08.2011 08:32

15 плюса

Синтаксис (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-компилятор предлагает вам этот ярлык из контекста времени компиляции (который не доступен для JVM и методов как Class.forNameво время выполнения!) ... Хорошо, в Clojure вы, конечно, всегда можете определите: (def Inner Outer$Inner)... или (def Tom Outer$Inner)или (def Harry Outer$Inner)или как угодно ... если вам это нравится больше.

Автор: Martin Valjavec Размещён: 04.06.2012 02:08
Вопросы из категории :
32x32