2010-02-03 4 views
74

Можно создать дубликат: How to access java-classes in the default-package?Как импортировать класс из пакета по умолчанию


Я использую 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, которую я хочу избежать (на самом деле - я не могу). Вот почему я поместил свой класс в пакет по умолчанию.

+1

Я нашел эту ссылку: http://stackoverflow.com/questions/283816/how-to-access-java-classes-in-the-default-package после создания этих вопросов. –

+0

Возможный дубликат [Что такое синтаксис для импорта класса в пакет по умолчанию в Java?] (Http://stackoverflow.com/questions/2030148/whats-the-syntax-to-import-a-class-in-a -default-package-in-java) – Pops

+0

Конечно, важный вопрос заключается в том, что класс ** и ** его код ** должны быть в пакете по умолчанию **. На данный момент любой ответ, кроме использования API отражения * (действительно, излишний для чего-то такого простого) * является ** не ** решением. Удивительно, как Java пытается получить свой торт (препятствовать пакету по умолчанию) и съесть его (сделать JNI настолько запутанным, большинство из нас в конечном итоге использует библиотеки DLL, которые требуют пакета по умолчанию). – ADTC

ответ

70

Java language spec От:

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

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

+1

Я использую отражение, чтобы решить мою проблему. –

+0

Ничего себе, я действительно не знаю java. Это была большая помощь. Угадайте, мне придется переместить мой класс в пакет ... – anhoppe

1

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

Для примера:

import my.packaged.DefaultClass; 

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

public class DefaultClass { 

    // Code here 

}
37

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

4

Я могу дать вам это предложение, Насколько известно из моего 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 и 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; 

Но окончательный совет: Хотя вы (Если вы Дельфи программист), либо они изменят прототипы этих функций и перекомпилируют файл dll, как только файл dll будет скомпилирован, вы не сможете изменить имя пакета вашего «Java» снова снова &. Потому что это будет снова потребует от вас или их изменить прототипы функций в Дельфах с измененными префиксы (например JAVA_yourpackage_with_underscores_for_inner_packages_JavaFileName_MethodName)

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

+0

Это хорошо для тех, кто пытается использовать Native Libraries в своих проектах. – Randnum

+0

yep. работает как очарование! – nikk

3

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

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

Используя 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"); 
+0

Это сработало для меня отлично !, спасибо! – Israelm

+1

Кажется, что отражение - единственный путь. У меня есть библиотека JNI, которая просто отказывается работать, когда в каком-либо пакете, кроме стандартного. Я не создал DLL, поэтому я не могу его перестроить. Все, что я делаю, должно быть в Java. Спасибо за сохранение дня :) – ADTC

-1
  1. Создать «корневой» пакет (папку) в проекте, например.

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

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

  3. Импорт нравится эта

    импорт source.YourClass;

+1

плохой ответ, если он этого хочет, он нуждается в нем по умолчанию, а не в каком-то специальном пакете – Enerccio

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

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

Во-первых, создать интерфейс для целевого класса 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); 
Смежные вопросы