web-dev-qa-db-fra.com

Comment accéder aux classes Java dans le package par défaut?

Je travaille maintenant avec d'autres dans un projet Grails. Je dois écrire des classes Java. Mais j'ai besoin d'accéder à un objet consultable créé avec groovy. Il semble que cet objet doive être placé dans le package par défaut.

Ma question est: Existe-t-il un moyen d'accéder à cet objet dans le package par défaut à partir d'une classe Java dans un package nommé?

93
Mnementh

Vous ne pouvez pas utiliser classes dans le package par défaut à partir d'un package nommé.
( Techniquement vous pouvez, comme indiqué dans Sharique Abdullah réponse grâce à l'API de réflexion, mais classes à partir des classes sans nom l'espace de noms ( n'est pas dans la portée dans une déclaration d'importation )

Avant J2SE 1.4, vous pouviez importer des classes à partir du package par défaut en utilisant une syntaxe comme celle-ci:

import Unfinished;

C'est plus autorisé . Ainsi, pour accéder à une classe de package par défaut à partir d'une classe packagée, il faut déplacer la classe de package par défaut dans un package qui lui est propre.

Si vous avez accès à la source générée par groovy, un post-traitement est nécessaire pour déplacer le fichier dans un package dédié et ajouter cette directive "package" à son début.


Mise à jour 2014: bogue 6975015 , pour JDK7 et JDK8, décrivez une interdiction uniforme plus stricte contre l'importation à partir d'un package sans nom.

TypeName doit être le nom canonique d'un type de classe, d'un type d'interface, d'un type d'énumération ou d'un type d'annotation.
Le type doit être soit un membre d'un package nommé , soit un membre d'un type dont le type lexical englobant le plus à l'extérieur est membre de un package nommé , ou une erreur de compilation se produit .


Andreas souligne dans les commentaires :

"pourquoi [le package par défaut] est-il en premier lieu? erreur de conception?"

Non, c'est délibéré.
JLS 7.4.2. Packages sans nom dit: "Les packages sans nom sont fournis par la plate-forme Java SE principalement pour des raisons de commodité lors du développement d'applications petites ou temporaires ou au tout début du développement ".

121
VonC

En fait, vous le pouvez.

En utilisant l'API de réflexions, vous pouvez accéder à n'importe quelle classe jusqu'à présent. Au moins j'ai pu :)

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

String fooReturned = (String)fooMethod.invoke(fooClass.newInstance(), "I did it");
59
Sharique Abdullah

Utilisez jarjar pour reconditionner le fichier jar avec la règle suivante:

rule * <target package name>.@1

Toutes les classes du package par défaut du fichier jar source se déplaceront vers le package cible, et pourront donc y accéder.

7
Sean

Vous pouvez utiliser des packages dans le code Groovy, et les choses fonctionneront très bien.

Cela peut signifier une réorganisation mineure du code sous grails-app Et un peu pénible au début, mais sur un grand projet Grails, il est logique d'organiser les choses dans des packages. Nous utilisons la convention Java convention de dénomination de package standard com.foo.<app>.<package>.

Tout avoir dans le package par défaut devient un obstacle à l'intégration, comme vous le constatez.

Les contrôleurs semblent être le seul artefact Grails (ou artefact) qui résiste à être placé dans un package Java. Probablement je n'ai pas encore trouvé le Convention pour cela.; -)

3
Ken Gentle