중복 가능성 : 기본 패키지의 자바 클래스에 액세스하는 방법은 무엇입니까?
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을 변경해야합니다 (정말로 할 수 없습니다). 그래서 기본 패키지에 수업을 넣었습니다.
답변
로부터 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
클래스 의 인스턴스를 만들고 이를 유형의 변수에 할당합니다 CalculationsInterface
.
Class<?> calcClass = Class.forName("Calculations");
CalculationsInterface api = (CalculationsInterface)calcClass.newInstance();
// Use it
double res = api.GetProgress(10);
답변
이 제안을 드릴 수 있습니다. 제 C 및 C ++ 프로그래밍 경험에서 아는 한, 같은 종류의 문제가 발생했을 때 “.C”파일의 이름을 변경하여 dll 작성 구조를 변경하여 해결했습니다. JNI 네이티브 기능을 구현 한 함수입니다. 예를 들어, “com.mypackage”패키지에 프로그램을 추가하려면 “.C”파일의 함수 / 메소드를 구현하는 JNI의 프로토 타입을 다음과 같이 변경합니다.
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
}
델파이를 처음 접했기 때문에 장담 할 수는 없지만 마침내 이렇게 말할 것입니다. (델파이와 JNI에 대해 인터넷 검색을 한 후 몇 가지를 배웠습니다.) : 네이티브의 델파이 구현을 제공 한 사람들에게 물어보십시오. 함수 이름을 다음과 같이 변경하는 코드 :
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
답변
아래에서 찾은 곳에서 :-
실제로 할 수 있습니다.
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
}
답변
새 패키지를 만든 다음 새 패키지에서 기본 패키지의 클래스를 이동하고 해당 클래스를 사용합니다.