2010-02-03 13 views
74

Eventuali duplicati: How to access java-classes in the default-package?Come importare una classe da pacchetto di default


Sto usando Eclipse 3.5 e ho creato un progetto con una certa struttura del pacchetto insieme al pacchetto di default. Ho una classe nel pacchetto predefinito - Calculations.java e voglio fare uso di quella classe in qualsiasi pacchetto (ad esempio in com.company.calc). Quando provo a rendere l'uso della classe che è nel pacchetto predefinito, mi dà un errore del compilatore. Non è in grado di riconoscere la classe nel pacchetto predefinito. Dov'è il problema?

Calculations.java - codice sorgente

public class Calculations { 
    native public int Calculate(int contextId); 
    native public double GetProgress(int contextId); 
    static { 
     System.loadLibrary("Calc"); 
    } 
} 

non posso mettere la mia classe in qualsiasi altro pacchetto. Questa classe ha alcuni metodi nativi implementati in Delphi. Se metto quella classe in una delle cartelle, dovrò apportare delle modifiche a quella DLL che voglio evitare (davvero - non posso). Ecco perché ho inserito la mia classe nel pacchetto predefinito.

+1

Ho trovato questo collegamento: http://stackoverflow.com/questions/283816/how-to-access-java-classes-in-the-default-package dopo aver creato queste domande. –

+0

possibile duplicato di [Qual è la sintassi per importare una classe in un pacchetto predefinito in Java?] (Http://stackoverflow.com/questions/2030148/whats-the-syntax-to-import-a-class-in-a -default-package-in-java) – Pops

+0

Ovviamente, il bit importante di questa domanda è che la classe ** e ** il suo codice ** devono essere nel pacchetto predefinito **. A partire da ora, qualsiasi risposta diversa dall'utilizzo dell'API di riflessione * (in realtà, un eccessivo utilizzo di qualcosa di così semplice) * è ** non ** una soluzione. È sconvolgente il modo in cui Java cerca di avere la sua torta (scoraggiare il pacchetto predefinito) e mangiarlo anch'esso (rendere così JNI così complicato, la maggior parte di noi finisce per usare DLL che richiedono un pacchetto predefinito). – ADTC

risposta

70

Dal Java language spec:

Si tratta di un errore di tempo di compilazione di importare un tipo dal pacchetto senza nome.

È necessario accedere alla classe tramite riflessione o qualche altro metodo indiretto.

+1

Uso la riflessione per risolvere il mio problema. –

+0

Wow davvero non conosco affatto Java. È stato un grande aiuto Suppongo che dovrò spostare la mia classe in un pacchetto ... – anhoppe

1

Sfortunatamente, non è possibile importare una classe senza che sia inclusa in un pacchetto. Questo è uno dei motivi per cui è altamente scoraggiato. Quello che proverei è una sorta di proxy - inserisci il tuo codice in un pacchetto che qualsiasi cosa può usare, ma se hai davvero bisogno di qualcosa nel pacchetto predefinito, rendi quella una classe molto semplice che inoltra le chiamate alla classe con il codice reale. O, ancora più semplice, basta estenderlo.

Per dare un esempio:

import my.packaged.DefaultClass; 

public class MyDefaultClass extends DefaultClass {}
package my.packaged.DefaultClass; 

public class DefaultClass { 

    // Code here 

}
37

classi nel pacchetto predefinito non possono essere importati da classi in pacchetti. Questo è il motivo per cui non dovresti usare il pacchetto predefinito.

4

vi posso dare questo suggerimento, Per quanto riguarda il know dal mio C e C esperienza di programmazione ++, Una volta, quando ho avuto il problema stesso genere di, ho risolto cambiando la struttura scritta dll nel file ".C" cambiando il nome della funzione che implementava la funzionalità nativa JNI. ad esempio, se si desidera aggiungere il proprio programma nel pacchetto "com.mypackage", Si modifica il prototipo dell'implementazione JNI ".C" la funzione/metodo per di file questo:

JNIEXPORT jint JNICALL 
Java_com_mypackage_Calculations_Calculate(JNIEnv *env, jobject obj, jint contextId) 
{ 
    //code goes here 
} 

JNIEXPORT jdouble JNICALL 
Java_com_mypackage_Calculations_GetProgress(JNIEnv *env, jobject obj, jint contextId) 
{ 
    //code goes here 
} 

Dato che io sono nuovo a Delfi, io non posso garantire, ma dire questo, infine, (ho imparato alcune cose dopo googling su Delphi e JNI): Chiedi quelle persone (se non si è l'uno) che hanno fornito l'attuazione Delphi del codice nativo per cambiare i nomi delle funzioni a qualcosa di simile:

function Java_com_mypackage_Calculations_Calculate(PEnv: PJNIEnv; Obj: JObject; contextId: JInt):JInt; {$IFDEF WIN32} stdcall; {$ENDIF} {$IFDEF LINUX} cdecl; {$ENDIF} 
var 
//Any variables you might be interested in 
begin 
    //Some code goes here 
end; 



function Java_com_mypackage_Calculations_GetProgress(PEnv: PJNIEnv; Obj: JObject; contextId: JInt):JDouble; {$IFDEF WIN32} stdcall; {$ENDIF} {$IFDEF LINUX} cdecl; {$ENDIF} 
var 
//Any variables you might be interested in 
begin 
//Some code goes here 
end; 

Ma, un consiglio finale: Anche se è (Se sei il Delphi programmatore) o loro cambieranno i prototipi di queste funzioni e ricompileranno il file dll, una volta che il file dll è compilato, non sarai in grado di cambiare il nome del pacchetto del file "Java" di nuovo & di nuovo. Perché, questo sarà di nuovo voi o li richiede di cambiare i prototipi delle funzioni in Delphi con prefissi modificati (per esempio JAVA_yourpackage_with_underscores_for_inner_packages_JavaFileName_MethodName)

penso che questo risolve il problema. Grazie e saluti, Harshal Malshe

+0

Questo è un bene per chiunque cerchi di utilizzare le librerie native nei propri progetti. – Randnum

+0

sì. funziona come il fascino! – nikk

3

Da alcuni dove ho trovato qui di seguito: -

In realtà, è possibile.

Utilizzando l'API di Reflections è possibile accedere a qualsiasi classe finora. Almeno ho potuto :)

pacchetto
Class fooClass = Class.forName("FooBar"); 
Method fooMethod = 
    fooClass.getMethod("fooMethod", new Class[] { String.class }); 

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

Ha funzionato perfettamente per me !, grazie! – Israelm

+1

Sembra che la riflessione sia l'unica strada da percorrere. Ho una libreria JNI che semplicemente si rifiuta di lavorare quando si trova in un pacchetto diverso da quello predefinito. Non ho creato la DLL, quindi non posso ricostruirla. Tutto ciò che faccio deve essere in Java. Grazie per aver salvato la giornata :) Risposta errata – ADTC

-1
  1. Crea "root" (cartella) nel progetto, per esempio.

    origine pacchetto; (.../path_to_project/source /)

  2. Sposta YourClass.class in una cartella di origine. (.../path_to_project/source/YourClass.class)

  3. Importa come questo

    source.YourClass importazione;

+1

, se lo desidera, ne ha bisogno in modo predefinito, non in qualche pacchetto personalizzato – Enerccio

-1
  1. Creare un nuovo pacchetto.
  2. Sposta i file dal pacchetto predefinito a quello nuovo.
5

C'è una soluzione alternativa per il tuo problema. È possibile utilizzare la riflessione per raggiungerlo.

In primo luogo, creare un'interfaccia per la classe di destinazione Calculatons:

package mypackage; 

public interface CalculationsInterface { 
    int Calculate(int contextId); 
    double GetProgress(int contextId); 

} 

Avanti, a rendere la vostra classe di destinazione implementare tale interfaccia:

public class Calculations implements mypackage.CalculationsInterface { 
    @Override 
    native public int Calculate(int contextId); 
    @Override 
    native public double GetProgress(int contextId); 
    static { 
     System.loadLibrary("Calc"); 
    } 
} 

Infine, l'uso di riflessione per creare un'istanza di Calculations classe e assegnarlo a una variabile di tipo CalculationsInterface:

Class<?> calcClass = Class.forName("Calculations"); 
CalculationsInterface api = (CalculationsInterface)calcClass.newInstance(); 
// Use it 
double res = api.GetProgress(10); 
Problemi correlati