2010-02-03 17 views
74

Powiel możliwe: How to access java-classes in the default-package?Jak zaimportować klasę z domyślnym pakietem


Używam Eclipse 3.5 i stworzyli projekt o pewnej strukturze pakietu wraz z domyślnym pakietem. Mam jedną klasę w domyślnym pakiecie - Calculations.java i chcę, aby korzystanie z tej klasy w dowolnym pakiecie (na przykład w com.company.calc). Kiedy próbuję użyć klasy, która znajduje się w domyślnym pakiecie, powoduje to błąd kompilatora. Nie jest w stanie rozpoznać klasy w domyślnym pakiecie. Gdzie jest problem?

Calculations.java - kod

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

źródło nie mogę umieścić moją klasę w każdym innym opakowaniu. Ta klasa ma pewne natywne metody, które są implementowane w Delphi. Jeśli umieściłem tę klasę w jednym z folderów, będę musiał dokonać zmian w tej bibliotece DLL, której chcę uniknąć (naprawdę - nie mogę). Właśnie dlatego umieściłem moją klasę w domyślnym pakiecie.

+1

Znalazłem ten link: http://stackoverflow.com/questions/283816/how-to-access-java-classes-in-the-default-package po utworzeniu tego pytania. –

+0

możliwy duplikat [Jaka jest składnia do importowania klasy w domyślnym pakiecie w Javie?] (Http://stackoverflow.com/questions/2030148/whats-the-syntax-to-import-a-class-in-a -default-package-in-java) – Pops

+0

Oczywiście ważną częścią tego pytania jest to, że klasa ** i ** jej kod ** musi znajdować się w domyślnym pakiecie **. Jak na razie każda inna odpowiedź, niż użycie interfejsu API do refleksji * (naprawdę, przesada dla czegoś tak prostego) * to ** nie ** rozwiązanie. To niesamowite, jak Java próbuje mieć swoje ciasto (odradzamy domyślny pakiet) i jemy też (zrób JNI tak zawiłe, większość z nas kończy używanie bibliotek DLL, które wymagają domyślnego pakietu). – ADTC

Odpowiedz

70

Z Java language spec:

Jest to błąd kompilacji czas importowania typ z pakietu bezimiennego.

Będziesz musiał uzyskać dostęp do klasy za pomocą refleksji lub innej metody pośredniej.

+1

Używam refleksji do rozwiązania mojego problemu. –

+0

Wow Naprawdę nie znam w ogóle javy. To była świetna pomoc. Chyba będę musiał przenieść moją klasę do pakietu ... – anhoppe

1

Niestety, nie można importować klasy bez jej umieszczenia w paczce. Jest to jeden z powodów, dla których jest wysoce odradzany. To, co chciałbym wypróbować, to rodzaj proxy - umieść swój kod w pakiecie, z którego można korzystać, ale jeśli naprawdę potrzebujesz czegoś w domyślnym pakiecie, ustaw tę bardzo prostą klasę, która przekazuje połączenia do klasy z prawdziwym kodem. Albo, jeszcze prostsze, po prostu przedłuż go.

Aby dać przykład:

import my.packaged.DefaultClass; 

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

public class DefaultClass { 

    // Code here 

}
37

Zajęcia w domyślnym pakiecie nie mogą być importowane przez klasy w pakietach. Dlatego nie powinieneś używać domyślnego pakietu.

4

Mogę dać ci tę sugestię, O ile wiem z mojego C i C++ doświadczenie w programowaniu, Kiedyś, gdy miałem ten sam kinda problem, rozwiązać go poprzez zmianę dll napisane strukturę „.c” Plik poprzez zmianę nazwy funkcji, która zaimplementowała rodzimą funkcjonalność JNI. na przykład, jeśli chcesz dodać swój program do pakietu "com.mypackage", Zmieniasz prototyp implementacji JNI ".C”funkcja File/metoda ta:

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 
} 

Ponieważ jestem nowy w Delphi, nie mogę zagwarantować wam, ale powiem to wreszcie (dowiedziałem się kilku rzeczy po googlowania o Delphi i JNI): Zapytaj ci ludzie (jeśli nie są one), którzy pod warunkiem wdrożenia Delphi natywnego kodu w celu zmiany nazwy funkcji do czegoś takiego:

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; 

Ale, ostateczną radę: Mimo, że (jeśli jesteś Delphi programista) lub je zmienić prototypy tych funkcji i przekompilować plik dll, po skompilowaniu pliku dll, nie będzie w stanie zmienić ponownie nazwę pakietu twojego pliku "Java" ponownie &. Ponieważ będzie to znowu wymaga albo je zmienić prototypy funkcji w Delphi ze zmienionymi przedrostków (np JAVA_yourpackage_with_underscores_for_inner_packages_JavaFileName_MethodName)

myślę, że to rozwiązuje problem. Dzięki i pozdrawiam, Harshal Malshe

+0

To jest dobre dla każdego, kto próbuje korzystać z Native Biblioteki w swoich projektach. – Randnum

+0

tak. działa jak urok! – nikk

3

Od gdzieś znalazłem poniżej: -

W rzeczywistości, można.

Korzystając z interfejsu API reflections, możesz uzyskać dostęp do dowolnej klasy. Przynajmniej udało mi się :)

pakiet
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

To zadziałało idealnie !, dzięki! – Israelm

+1

Wygląda na to, że refleksja jest jedyną drogą. Mam bibliotekę JNI, która po prostu odmawia pracy, gdy jest w pakiecie innym niż domyślny. Nie zbudowałem biblioteki DLL, więc nie mogę jej odbudować. Wszystko, co robię, musi być w Javie. Dziękuję za uratowanie dnia :) – ADTC

-1
  1. Tworzenie "root" (folder) w projekcie, na przykład.

    źródło pakietu; (.../path_to_project/source /)

  2. Przenieś swój ClassClass.class do folderu źródłowego. (.../path_to_project/źródło/YourClass.class)

  3. importu jak tego

    source.YourClass przywozowych;

+1

Zła odpowiedź, jeśli tego chce, potrzebuje go domyślnie, a nie w niestandardowym pakiecie – Enerccio

-1
  1. Utwórz nowy pakiet.
  2. Przenieś pliki z pakietu domyślnego do nowego.
5

Istnieje obejście tego problemu. Możesz użyć odbicia, aby to osiągnąć.

Najpierw utwórz interfejs dla swojej klasie docelowej Calculatons:

package mypackage; 

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

} 

Następnie dokonać klasa cel wdrożenia tego interfejsu:

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

Wreszcie użycie refleksji aby utworzyć wystąpienie Calculations klasie i przypisz go do zmiennej o typie CalculationsInterface:

Class<?> calcClass = Class.forName("Calculations"); 
CalculationsInterface api = (CalculationsInterface)calcClass.newInstance(); 
// Use it 
double res = api.GetProgress(10); 
Powiązane problemy