Вопрос-ответ

How to access java-classes in the default-package?

Как получить доступ к java-классам в пакете по умолчанию?

Сейчас я работаю вместе с другими над проектом grails. Мне нужно написать несколько Java-классов. Но мне нужен доступ к объекту с возможностью поиска, созданному с помощью groovy. Кажется, что этот объект должен быть помещен в default-package.

Мой вопрос таков: Есть ли способ получить доступ к этому объекту в пакете по умолчанию из Java-класса в именованном пакете?

Переведено автоматически
Ответ 1

Вы не можете использовать классы в пакете по умолчанию из именованного пакета.
(Технически вы можете, как показано в ответе Шарика Абдуллы, через reflection API, но классы из неназванного пространства имен не входят в область видимости в объявлении импорта)

До J2SE 1.4 вы могли импортировать классы из пакета по умолчанию, используя синтаксис, подобный этому:

import Unfinished;

Это больше не разрешено. Таким образом, для доступа к классу пакета по умолчанию из упакованного класса требуется переместить класс пакета по умолчанию в собственный пакет.

Если у вас есть доступ к исходному коду, сгенерированному groovy, требуется некоторая постобработка, чтобы переместить файл в выделенный пакет и добавить эту директиву "package" в его начале.


Обновление 2014: ошибка 6975015 для JDK7 и JDK8 описывает еще более строгий запрет на импорт из неназванного пакета.


В TypeName должно быть каноническое имя типа класса, типа интерфейса, типа перечисления или типа аннотации.
Тип должен быть либо членом именованного пакета, либо членом типа, самый внешний лексически охватывающий тип которого является членом именованного пакета, иначе возникает ошибка времени компиляции.



Андреас указывает в комментариях:



"почему [пакет по умолчанию] там вообще? ошибка разработки?"



Нет, это сделано намеренно.

JLS 7.4.2. Безымянные пакеты гласит: "Безымянные пакеты предоставляются платформой Java SE в основном для удобства при разработке небольших или временных приложений или при только начале разработки".


Ответ 2

На самом деле, вы можете.

Используя reflections API, вы можете получить доступ к любому классу на данный момент. По крайней мере, я смог :)

Class fooClass = Class.forName("FooBar");
Method fooMethod = fooClass.getMethod("fooMethod", String.class);

String fooReturned = (String)fooMethod.invoke(fooClass.newInstance(), "I did it");
Ответ 3

Используйте jarjar для переупаковки файла jar со следующим правилом:

rule * <target package name>.@1

Все классы в пакете по умолчанию исходного файла jar переместятся в целевой пакет, таким образом, смогут получить доступ.

Ответ 4

Вы можете использовать пакеты в Groovy коде, и все будет работать просто отлично.

Это может означать незначительную реорганизацию кода в grails-app и поначалу немного затруднительно, но в большом проекте grails просто имеет смысл упорядочивать вещи в пакетах. Мы используем стандартное соглашение об именовании пакетов Java com.foo.<app>.<package>.

Как вы видите, наличие всего в пакете по умолчанию становится препятствием для интеграции.

Контроллеры, похоже, являются единственным артефактом Grails (или artefact), который не помещается в пакет Java. Вероятно, я просто еще не разобрался с Convention для этого. ;-)

java