Come accedere alle classi java nel pacchetto predefinito?


98

Adesso sto lavorando insieme ad altri in un progetto Grails. Devo scrivere alcune classi Java. Ma ho bisogno di accedere a un oggetto ricercabile creato con groovy. Sembra che questo oggetto debba essere posizionato nel pacchetto predefinito.

La mia domanda è: c'è un modo per accedere a questo oggetto nel pacchetto predefinito da una classe Java in un pacchetto denominato?

Risposte:


129

Non è possibile utilizzare classi nel pacchetto predefinito da un pacchetto denominato.
( Tecnicamente puoi, come mostrato nella risposta di Sharique Abdullah tramite l'API di riflessione, ma le classi dallo spazio dei nomi senza nome non sono nell'ambito di una dichiarazione di importazione )

Prima di J2SE 1.4 era possibile importare classi dal pacchetto predefinito utilizzando una sintassi come questa:

import Unfinished;

Non è più permesso . Quindi, per accedere a una classe di pacchetto predefinita dall'interno di una classe in pacchetto, è necessario spostare la classe di pacchetto predefinita in un pacchetto a sé stante.

Se hai accesso al sorgente generato da groovy, è necessario un po 'di post-elaborazione per spostare il file in un pacchetto dedicato e aggiungere questa direttiva "pacchetto" all'inizio.


Aggiornamento 2014: bug 6975015 , per JDK7 e JDK8, descrive un divieto ancora più severo contro l'importazione da pacchetti senza nome.

La TypeNamedeve essere il nome canonico di un tipo di classe, tipo di interfaccia, tipo enum, o il tipo di annotazione.
Il tipo deve essere un membro di un pacchetto denominato o un membro di un tipo il cui tipo di inclusione lessicale più esterno è un membro di un pacchetto denominato , altrimenti si verifica un errore in fase di compilazione .


Andreas sottolinea nei commenti :

"perché [il pacchetto predefinito] è lì in primo luogo? errore di progettazione?"

No, è intenzionale.
JLS 7.4.2. Pacchetti senza nome dice: "I pacchetti senza nome sono forniti dalla piattaforma Java SE principalmente per comodità durante lo sviluppo di applicazioni piccole o temporanee o quando lo sviluppo è appena iniziato".


7
Come ho già spiegato ad altre persone, il pacchetto predefinito è un cittadino di seconda classe nel mondo Java. Basta non farlo. :-)
Chris Jester-Young

1
Sembra che devo imparare Groovy (su un progetto molto limitato nel tempo) o il codice nel pacchetto predefinito. :-(
Mnementh

11
@ ChrisJester-Young, se sì, perché è lì in primo luogo? errore di progettazione?
Pacerier

Perché è stato deprecato?
Suzan Cioc

@SuzanCioc intendi: "perché dopo J2SE1.4 non puoi più accedere al pacchetto predefinito?"
VonC

61

In effetti puoi.

Utilizzando l'API Reflections puoi accedere a qualsiasi classe fino ad ora. Almeno sono stato in grado di :)

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

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

Per Scala, il codice seguente funziona: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
Ottima risposta, +1. Poiché la domanda era fantastica, tuttavia, puoi usare la digitazione a papera (come Duct taping, immagino) ...Class.forName("FooBar").newInstance().fooMethod("I did it")
Bill K

7

Usa jarjar per ricompattare il file jar con la seguente regola:

rule * <target package name>.@1

Tutte le classi nel pacchetto predefinito del file jar di origine si sposteranno nel pacchetto di destinazione, quindi potranno accedere.


4
una demo di come utilizzare jarjar sarebbe fantastico
BiGGZ

@BiGGZ: vedere il file README.md sul repository github jarjar per vedere come utilizzare jarjar con ant, gradle o la riga di comando.
Lucidiot

3

Puoi usare i pacchetti nel Groovycodice e le cose funzioneranno perfettamente.

Può significare una piccola riorganizzazione del codice grails-appe un po 'di fastidio all'inizio, ma su un grande progetto Graal, ha senso organizzare le cose in pacchetti. Usiamo la convenzione di denominazione dei pacchetti standard Java com.foo.<app>.<package>.

Avere tutto nel pacchetto predefinito diventa un ostacolo all'integrazione, come stai scoprendo.

I controller sembrano essere l'unico artefatto (o artefatto) di Grails che resiste a essere inserito in un pacchetto Java. Probabilmente non l'ho ancora capito Convention. ;-)


0

solo per completare l'idea:

Dall'interno del pacchetto predefinito è possibile accedere agli oggetti che risiedono nei pacchetti denominati.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.