Как импортировать класс из пакета по умолчанию - PullRequest
87 голосов
/ 03 февраля 2010

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


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

Calculations.java - исходный код

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

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

Ответы [ 9 ]

79 голосов
/ 03 февраля 2010

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

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

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

41 голосов
/ 03 февраля 2010

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

7 голосов
/ 29 сентября 2016

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

Сначала создайте интерфейс для целевого класса 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 и присвоить его переменной типа CalculationsInterface:

Class<?> calcClass = Class.forName("Calculations");
CalculationsInterface api = (CalculationsInterface)calcClass.newInstance();
// Use it 
double res = api.GetProgress(10);
4 голосов
/ 09 апреля 2014

От того, где я нашел ниже: -

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

Используя 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");
4 голосов
/ 14 марта 2010

Я могу дать вам это предложение, Насколько я знаю из моего опыта программирования на 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, я не могу гарантировать вам, но скажу это наконец, (я узнал несколько вещей после поиска в Google о 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)

Я думаю, что это решает проблему. Спасибо и всего наилучшего, Харшал Малше

1 голос
/ 03 февраля 2010

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

Чтобы привести пример:

import my.packaged.DefaultClass;

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

public class DefaultClass {

   // Code here

}
0 голосов
/ 31 марта 2018

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

0 голосов
/ 09 мая 2015
  1. Создать новый пакет.
  2. Переместите файлы из пакета по умолчанию в новый.
0 голосов
/ 12 мая 2014
  1. Создать «корневой» пакет (папку) в вашем проекте, например.

    source source;(... / path_to_project / source /)

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

  3. Импортировать как этот

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

...