Как импортировать класс из пакета по умолчанию

Возможные Дубликаты: как получить доступ к java-классам в пакете по умолчанию?


Я использую Eclipse 3.5, и я создал проект с некоторой структурой пакета вместе с пакетом по умолчанию. У меня есть один класс в пакете по умолчанию -расчетов.java и я хочу использовать этот класс в любом из пакетов (например, в com.company.calc). Когда я пытаюсь использовать класс, который находится в пакете по умолчанию, это дает мне ошибку компилятора. Он не может распознать класс в пакете по умолчанию. В чем проблема?

расчетов.на Java исходный код

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

Я не могу поместить свой класс в какой-либо другой пакет. Этот класс имеет некоторые собственные методы, которые реализованы в Delphi. Если я помещу этот класс в любую из папок, мне придется внести изменения в ту DLL, которую я хочу избежать (действительно - я не могу). Вот почему я поместил свой класс в пакет по умолчанию.

9 ответов


с спецификация языка Java:

Это ошибка времени компиляции для импорта типа из неназванного пакета.

вам нужно будет получить доступ к классу через отражение или какой-либо другой косвенный метод.


классы в пакете по умолчанию не могут быть импортированы классы в пакеты. Вот почему не следует использовать пакет по умолчанию.


есть решение для вашей проблемы. Вы можете использовать отражение, чтобы достичь этого.

во-первых, создайте интерфейс для вашего целевого класса Calculatons :

package mypackage;

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

}

далее, сделайте свой целевой класс реализовать этот интерфейс:

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

наконец, использовать отражение для создания экземпляра Calculations class и назначьте его переменной типа CalculationsInterface :

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

Я могу дать вам это предложение, Насколько я знаю из моего опыта программирования на C и C++ , Однажды, когда у меня была такая же проблема, я решил ее, изменив написанную структуру dll в ".C " файл путем изменения имени функции, которая реализовала собственную функциональность JNI. например, если вы хотите добавить свою программу в пакет " com.пакета mypackage", Вы меняете прототип реализации JNI".C " Функция/метод файла для этого:

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
}

поскольку я новичок в delphi, я не могу гарантировать вам, но скажу это, наконец, (я узнал несколько вещей после того, как погуглил о Delphi и JNI): Спросите тех людей( если вы не тот), которые предоставили реализацию Delphi собственного кода, чтобы изменить имена функций на что-то вроде этого:

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;

но, последний совет: хотя вы (если вы программист delphi) или они изменят прототипы этих функций и перекомпилируют dll-файл, как только dll-файл будет скомпилирован, вы не сможете изменить имя пакета вашего файла "Java" снова и снова. Потому что это снова потребует от вас или их изменить прототипы функций в delphi с измененными префиксами (например, JAVA_yourpackage_with_underscores_for_inner_packages_javafilename_methodname)

Я думаю, что это решает проблему. Спасибо и с уважением, Harshal Malshe


из некоторых, где я нашел ниже :-

в самом деле, вы можете.

используя reflections API, вы можете получить доступ к любому классу. По крайней мере, я смог :)

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

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

к сожалению, вы не можете импортировать класс без пакета. Это одна из причин крайне нежелательно. Я бы попробовал своего рода прокси-сервер-поместите свой код в пакет, который может использовать что угодно, но если вам действительно нужно что-то в пакете по умолчанию, сделайте это очень простым классом, который перенаправляет вызовы классу с реальным кодом. Или, что еще проще, просто расширьте его.

приведу пример:

import my.packaged.DefaultClass;

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

public class DefaultClass {

   // Code here

}

создать новый пакет А затем переместите классы пакета по умолчанию в новый пакет и используйте эти классы


  1. создать новый пакет.
  2. переместите файлы из пакета по умолчанию в новый.

  1. создаем "корневой" пакет (папку) в вашем проекте, например.

    источник пакета; (.../ path_to_project / source/)

  2. Переместить Свой Класс.класс в исходную папку. (.../ path_to_project / source / YourClass.класс)

  3. импорт такой

    источник импорта.В yourclass;