我正在使用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进行更改(实际上 - 我不能)。这就是我将我的课程放在默认包中的原因。
答案 0 :(得分:78)
答案 1 :(得分:41)
默认包中的类不能由包中的类导入。这就是您不应该使用默认包的原因。
答案 2 :(得分:6)
您的问题有一个解决方法。您可以使用反射来实现它。
首先,为目标类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);
答案 3 :(得分:4)
我可以给你这个建议, 据我所知的C和C ++编程经验, 有一次,当我遇到同样的问题时,我通过改变实现JNI本机功能的函数的名称来改变“.C”文件中的dll编写结构来解决它。 例如,如果您想在程序包“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
}
由于我是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”文件的名称&amp;再次。 因为,这将再次要求您或他们使用更改的前缀更改delphi中函数的原型(例如JAVA_yourpackage_with_underscores_for_inner_packages_JavaFileName_MethodName)
我认为这解决了这个问题。 感谢致敬, Harshal Malshe
答案 4 :(得分:4)
从我在下面找到的地方: -
事实上,你可以。
使用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");
答案 5 :(得分:1)
不幸的是,如果没有它在一个包中,你就无法导入它。这是非常沮丧的原因之一。我会尝试的是一种代理 - 将您的代码放入任何可以使用的包中,但如果您确实需要默认包中的某些内容,请将其设置为一个非常简单的类,它使用实际代码将调用转发给类。或者,更简单,只需延长它。
举个例子:
import my.packaged.DefaultClass;
public class MyDefaultClass extends DefaultClass {}
package my.packaged.DefaultClass;
public class DefaultClass {
// Code here
}
答案 6 :(得分:-1)
创建一个新包 然后在新包中移动默认包的类并使用这些类
答案 7 :(得分:-2)
创建&#34; root&#34;例如,项目中的包(文件夹)。
包源; (... / path_to_project /源极/)
将YourClass.class移动到源文件夹中。 (... / path_to_project /源极/ YourClass.class)
像这样导入
import source.YourClass;
答案 8 :(得分:-2)