如何从默认包导入类?

时间:2022-05-07 16:55:05

Possible Duplicate: How to access java-classes in the default-package?

可能的副本:如何在默认包中访问java类?


I am using Eclipse 3.5 and I have created a project with some package structure along with the default package. I have one class in default package - Calculations.java and I want to make the use of that class in any of the package (for instance in com.company.calc). When I try to make the use of the class which is in the default package, it's giving me a compiler error. It's not able to recognise the class in default package. Where is the problem?

我使用的是Eclipse 3.5,我创建了一个带有包结构和默认包的项目。我有一个类的默认包-计算。java和我想在任何一个包中使用这个类(例如,com.company.calc)。当我尝试使用默认包中的类时,它会给我一个编译器错误。它不能识别默认包中的类。问题在哪里?

Calculations.java - source code

计算。java——源代码

public class Calculations {
    native public int Calculate(int contextId);
    native public double GetProgress(int contextId);
    static  {
        System.loadLibrary("Calc");
    }
}

I can't put my class in any other package. This class has some native methods which are implemented in Delphi. If I put that class in any of the folders, I will have to make changes to that DLL which I want to avoid (really - I can not). That's why I put my class in the default package.

我不能把我的课放在其他的包里。这个类有一些在Delphi中实现的本地方法。如果我把这个类放到任何一个文件夹中,我就必须修改那个我想要避免的DLL(真的,我不能)。这就是为什么我把类放在默认的包里。

9 个解决方案

#1


70  

From the Java language spec:

从Java语言规范:

It is a compile time error to import a type from the unnamed package.

从未命名的包中导入类型是一个编译时错误。

You'll have to access the class via reflection or some other indirect method.

您必须通过反射或其他间接方法访问该类。

#2


37  

Classes in the default package cannot be imported by classes in packages. This is why you should not use the default package.

默认包中的类不能由包中的类导入。这就是为什么不应该使用默认包。

#3


5  

There is a workaround for your problem. You can use reflection to achieve it.

有一个解决你问题的办法。您可以使用反射来实现它。

First, create an interface for your target class Calculatons :

首先,为您的目标类Calculatons创建一个接口:

package mypackage;

public interface CalculationsInterface {  
    int Calculate(int contextId);  
    double GetProgress(int contextId);  

}

Next, make your target class implement that interface:

接下来,让您的目标类实现这个接口:

public class Calculations implements mypackage.CalculationsInterface {
    @Override
    native public int Calculate(int contextId);
    @Override
    native public double GetProgress(int contextId);
    static  {
        System.loadLibrary("Calc");
    }
}

Finally, use reflection to create an instance of Calculations class and assign it to a variable of type CalculationsInterface :

最后,使用反射创建一个计算类实例,并将其赋给类型CalculationsInterface的变量:

Class<?> calcClass = Class.forName("Calculations");
CalculationsInterface api = (CalculationsInterface)calcClass.newInstance();
// Use it 
double res = api.GetProgress(10);

#4


4  

I can give you this suggestion, As far as know from my C and C++ Programming experience, Once, when I had the same kinda problem, I solved it by changing the dll written structure in ".C" File by changing the name of the function which implemented the JNI native functionality. for example, If you would like to add your program in the package "com.mypackage", You change the prototype of the JNI implementing ".C" File's function/method to this one:

我可以给你这个建议,在我的C和c++编程经验中,有一次,当我有同样的问题时,我通过改变dll的书面结构来解决它。通过更改实现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
}

Since I am new to delphi, I can not guarantee you but will say this finally, (I learned few things after googling about Delphi and JNI): Ask those people (If you are not the one) who provided the Delphi implementation of the native code to change the function names to something like this:

因为我新德尔菲,我不能保证你但会说这最后,(我学会了一些东西在google上搜索关于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;

But, A final advice: Although you (If you are the delphi programmer) or them will change the prototypes of these functions and recompile the dll file, once the dll file is compiled, you will not be able to change the package name of your "Java" file again & again. Because, this will again require you or them to change the prototypes of the functions in delphi with changed prefixes (e.g. JAVA_yourpackage_with_underscores_for_inner_packages_JavaFileName_MethodName)

但是,最后的建议是:尽管您(如果您是delphi程序员)或他们将更改这些函数的原型并重新编译dll文件,一旦dll文件被编译,您将不能一次又一次地更改“Java”文件的包名。因为,这将再次要求您或他们更改delphi中函数的原型,并更改前缀(例如JAVA_yourpackage_with_underscores_for_inner_packages_JavaFileName_MethodName)。

I think this solves the problem. Thanks and regards, Harshal Malshe

我认为这解决了问题。谢谢和问候,Harshal Malshe。

#5


3  

From some where I found below :-

从我在下面找到的一些地方:-。

In fact, you can.

事实上,你可以。

Using reflections API you can access any class so far. At least I was able to :)

使用反射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");

#6


1  

Unfortunately, you can't import a class without it being in a package. This is one of the reasons it's highly discouraged. What I would try is a sort of proxy -- put your code into a package which anything can use, but if you really need something in the default package, make that a very simple class which forwards calls to the class with the real code. Or, even simpler, just have it extend.

不幸的是,如果没有包,就不能导入类。这是它极度气馁的原因之一。我要尝试的是一种代理——将您的代码放入一个任何可以使用的包中,但是如果您确实需要在默认包中使用一些东西,那么就使它成为一个非常简单的类,它用真正的代码将调用转发给类。或者,更简单的是,让它扩展。

To give an example:

举一个例子:

import my.packaged.DefaultClass;

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

public class DefaultClass {

   // Code here

}

#7


-1  

Create a new package And then move the classes of default package in new package and use those classes

创建一个新包,然后在新包中移动默认包的类,并使用这些类。

#8


-2  

  1. Create a new package.
  2. 创建一个新包。
  3. Move your files from the default package to the new one.
  4. 将您的文件从默认包移动到新的包。

#9


-2  

  1. Create "root" package (folder) in your project, for example.

    例如,在您的项目中创建“根”包(文件夹)。

    package source; (.../path_to_project/source/)

    包的来源;(…/ path_to_project /源/)

  2. Move YourClass.class into a source folder. (.../path_to_project/source/YourClass.class)

    YourClass移动。类进入源文件夹。(…/ path_to_project /源/ YourClass.class)

  3. Import like this

    这样的导入

    import source.YourClass;

    进口source.YourClass;

#1


70  

From the Java language spec:

从Java语言规范:

It is a compile time error to import a type from the unnamed package.

从未命名的包中导入类型是一个编译时错误。

You'll have to access the class via reflection or some other indirect method.

您必须通过反射或其他间接方法访问该类。

#2


37  

Classes in the default package cannot be imported by classes in packages. This is why you should not use the default package.

默认包中的类不能由包中的类导入。这就是为什么不应该使用默认包。

#3


5  

There is a workaround for your problem. You can use reflection to achieve it.

有一个解决你问题的办法。您可以使用反射来实现它。

First, create an interface for your target class Calculatons :

首先,为您的目标类Calculatons创建一个接口:

package mypackage;

public interface CalculationsInterface {  
    int Calculate(int contextId);  
    double GetProgress(int contextId);  

}

Next, make your target class implement that interface:

接下来,让您的目标类实现这个接口:

public class Calculations implements mypackage.CalculationsInterface {
    @Override
    native public int Calculate(int contextId);
    @Override
    native public double GetProgress(int contextId);
    static  {
        System.loadLibrary("Calc");
    }
}

Finally, use reflection to create an instance of Calculations class and assign it to a variable of type CalculationsInterface :

最后,使用反射创建一个计算类实例,并将其赋给类型CalculationsInterface的变量:

Class<?> calcClass = Class.forName("Calculations");
CalculationsInterface api = (CalculationsInterface)calcClass.newInstance();
// Use it 
double res = api.GetProgress(10);

#4


4  

I can give you this suggestion, As far as know from my C and C++ Programming experience, Once, when I had the same kinda problem, I solved it by changing the dll written structure in ".C" File by changing the name of the function which implemented the JNI native functionality. for example, If you would like to add your program in the package "com.mypackage", You change the prototype of the JNI implementing ".C" File's function/method to this one:

我可以给你这个建议,在我的C和c++编程经验中,有一次,当我有同样的问题时,我通过改变dll的书面结构来解决它。通过更改实现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
}

Since I am new to delphi, I can not guarantee you but will say this finally, (I learned few things after googling about Delphi and JNI): Ask those people (If you are not the one) who provided the Delphi implementation of the native code to change the function names to something like this:

因为我新德尔菲,我不能保证你但会说这最后,(我学会了一些东西在google上搜索关于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;

But, A final advice: Although you (If you are the delphi programmer) or them will change the prototypes of these functions and recompile the dll file, once the dll file is compiled, you will not be able to change the package name of your "Java" file again & again. Because, this will again require you or them to change the prototypes of the functions in delphi with changed prefixes (e.g. JAVA_yourpackage_with_underscores_for_inner_packages_JavaFileName_MethodName)

但是,最后的建议是:尽管您(如果您是delphi程序员)或他们将更改这些函数的原型并重新编译dll文件,一旦dll文件被编译,您将不能一次又一次地更改“Java”文件的包名。因为,这将再次要求您或他们更改delphi中函数的原型,并更改前缀(例如JAVA_yourpackage_with_underscores_for_inner_packages_JavaFileName_MethodName)。

I think this solves the problem. Thanks and regards, Harshal Malshe

我认为这解决了问题。谢谢和问候,Harshal Malshe。

#5


3  

From some where I found below :-

从我在下面找到的一些地方:-。

In fact, you can.

事实上,你可以。

Using reflections API you can access any class so far. At least I was able to :)

使用反射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");

#6


1  

Unfortunately, you can't import a class without it being in a package. This is one of the reasons it's highly discouraged. What I would try is a sort of proxy -- put your code into a package which anything can use, but if you really need something in the default package, make that a very simple class which forwards calls to the class with the real code. Or, even simpler, just have it extend.

不幸的是,如果没有包,就不能导入类。这是它极度气馁的原因之一。我要尝试的是一种代理——将您的代码放入一个任何可以使用的包中,但是如果您确实需要在默认包中使用一些东西,那么就使它成为一个非常简单的类,它用真正的代码将调用转发给类。或者,更简单的是,让它扩展。

To give an example:

举一个例子:

import my.packaged.DefaultClass;

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

public class DefaultClass {

   // Code here

}

#7


-1  

Create a new package And then move the classes of default package in new package and use those classes

创建一个新包,然后在新包中移动默认包的类,并使用这些类。

#8


-2  

  1. Create a new package.
  2. 创建一个新包。
  3. Move your files from the default package to the new one.
  4. 将您的文件从默认包移动到新的包。

#9


-2  

  1. Create "root" package (folder) in your project, for example.

    例如,在您的项目中创建“根”包(文件夹)。

    package source; (.../path_to_project/source/)

    包的来源;(…/ path_to_project /源/)

  2. Move YourClass.class into a source folder. (.../path_to_project/source/YourClass.class)

    YourClass移动。类进入源文件夹。(…/ path_to_project /源/ YourClass.class)

  3. Import like this

    这样的导入

    import source.YourClass;

    进口source.YourClass;