如何从默认包中导入一个类
可能重复: 如何访问默认包中的Java类?
我正在使用Eclipse 3.5,我已经创build了一个包含默认包的包结构的项目。 我有一个类的默认包 – 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语言规范 :
从未命名包中导入types是编译时错误。
您将不得不通过reflection或其他间接方法访问该类。
默认包中的类不能由包中的类导入。 这就是为什么你不应该使用默认包。
我可以给你这个build议,就我的C和C ++编程经验而言,有一次,当我遇到同样的问题时,我通过改变“.C”文件中的dll写入结构来解决它,它实现了JNI本地function。 例如,如果您想将程序添加到“com.mypackage”包中,则将实现“.C”文件的function/方法的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上search了一些东西之后学到了一些东西):问那些提供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;
但是,最后的build议:虽然你(如果你是delphi程序员)或者他们会改变这些函数的原型并重新编译dll文件,一旦dll文件被编译,你将无法更改你的软件包名称“Java”文件再次。 因为,这将再次要求你或他们改变delphifunction的原型与改变的前缀(例如JAVA_yourpackage_with_underscores_for_inner_packages_JavaFileName_MethodName)
我认为这解决了这个问题。 感谢和问候,哈萨尔·马尔谢
有一个解决你的问题。 你可以使用reflection来实现它。
首先,为您的目标类Calculatons
创build一个接口:
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"); } }
最后,使用reflection来创buildCalculations
类的实例,并将其分配给CalculationsInterface
types的variables:
Class<?> calcClass = Class.forName("Calculations"); CalculationsInterface api = (CalculationsInterface)calcClass.newInstance(); // Use it double res = api.GetProgress(10);
从我在下面find的一些地方:
其实你可以。
使用reflectionAPI,您可以访问任何类到目前为止。 至less我能够:)
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 }
- 创build一个新的包。
- 将文件从默认包移到新包。
-
例如,在您的项目中创build“根”包(文件夹)。
包源程序 (… / path_to_project /源极/)
-
将YourClass.class移动到源文件夹中。 (… / path_to_project /源极/ YourClass.class)
-
像这样导入
import source.YourClass;