Как получить доступ к java-классам в default-package? - PullRequest
91 голосов
/ 12 ноября 2008

Я сейчас работаю вместе с другими в проекте Grails. Я должен написать несколько Java-классов. Но мне нужен доступ к поисковому объекту, созданному с помощью groovy. Похоже, этот объект должен быть помещен в default-package.

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

Ответы [ 4 ]

120 голосов
/ 12 ноября 2008

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

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

import Unfinished;

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

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


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

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


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

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

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

59 голосов
/ 18 февраля 2009

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

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

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

String fooReturned = (String)fooMethod.invoke(fooClass.newInstance(), "I did it");
7 голосов
/ 13 марта 2014

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

rule * <target package name>.@1

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

3 голосов
/ 12 ноября 2008

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

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

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

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

...