如何从默认包中导入一个类

可能重复: 如何访问默认包中的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类的实例,并将其分配给CalculationsInterfacetypes的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 } 
  1. 创build一个新的包。
  2. 将文件从默认包移到新包。
  1. 例如,在您的项目中创build“根”包(文件夹)。

    包源程序 (… / path_to_project /源极/)

  2. 将YourClass.class移动到源文件夹中。 (… / path_to_project /源极/ YourClass.class)

  3. 像这样导入

    import source.YourClass;