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

98

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

Ma question est la suivante: 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é?

Mnementh
la source

Réponses:

129

Vous ne pouvez pas utiliser de classes dans le package par défaut à partir d'un package nommé.
( Techniquement, vous pouvez, comme indiqué dans la réponse de Sharique Abdullah via l'API de réflexion, mais les classes de l'espace de noms sans nom ne sont pas dans la portée d'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;

Ce n'est plus autorisé . Ainsi, pour accéder à une classe de package par défaut depuis une classe de package, 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: le bogue 6975015 , pour JDK7 et JDK8, décrit une interdiction encore plus stricte contre l'importation depuis un paquet sans nom.

Le TypeNamedoit ê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 englobant lexicalement le plus externe est membre d'un package nommé , ou une erreur de compilation se produit .


Andreas souligne dans les commentaires :

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

Non, c'est délibéré.
JLS 7.4.2. Unnamed Packages 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 début du développement".

VonC
la source
7
Comme je l'ai expliqué à d'autres personnes auparavant, le package par défaut est un citoyen de deuxième classe dans le monde Java. Ne fais pas ça. :-)
Chris Jester-Young
1
Il semble que je dois apprendre Groovy (sur un projet très limité dans le temps) ou le code dans le package par défaut. :-(
Mnementh
11
@ ChrisJester-Young si oui, pourquoi est-il là en premier lieu? erreur de conception?
Pacerier
Pourquoi est-il obsolète?
Suzan Cioc
@SuzanCioc voulez-vous dire: "pourquoi après J2SE1.4, ne pouvez-vous plus accéder au package par défaut?"
VonC
61

En fait, vous pouvez.

En utilisant l'API 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");
Holger
la source
Pour Scala, le code suivant fonctionne:val bar = "hi"; val fooClass = Class.forName("FooClass"); val fooMethod = fooClass.getMethod("foo", classOf[Array[String]]); val fooReturned = fooMethod.invoke(fooClass.newInstance(), Array(bar));
Jus12
2
Excellente réponse, +1. Comme la question était groovy, cependant, vous pouvez utiliser la saisie de canard (comme le ruban adhésif, je suppose) ...Class.forName("FooBar").newInstance().fooMethod("I did it")
Bill K
7

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 seront déplacées vers le package cible et pourront donc y accéder.

Sean
la source
4
une démonstration de l'utilisation de jarjar serait géniale
BiGGZ
@BiGGZ: Voir le fichier README.md sur le dépôt jarjar github pour voir comment utiliser jarjar avec ant, gradle ou la ligne de commande.
Lucidiot
3

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

Cela peut signifier une réorganisation mineure du code sous grails-appet un peu pénible au début, mais sur un gros projet Grails, il est juste logique d'organiser les choses dans des packages. Nous utilisons la convention de dénomination de package standard Javacom.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. Je n'ai probablement pas encore trouvé le Conventionpour ça. ;-)

Ken Gentle
la source
0

juste pour compléter l'idée:

Depuis l'intérieur du package par défaut, vous pouvez accéder aux objets résidant dans des packages nommés.

Duracell De Monaco
la source