使用相同的包名调用与其他函数同名的函数

时间:2013-06-28 08:03:09

标签: java

我的Java项目有问题,我有一堆项目(例如A,B,C ......)碰巧在路径中的工具文件夹中有一个Tools类,例如src.tool.Tools,所有这些路径和相同的类名相同。

现在,我的项目Z在其构建路径中具有所有这些项目(A,B,C ......)。我如何确保在导入一个Tool类时导入我真正需要的那个?

更复杂,如果在A.Tool我有一个方法,如public int tool(){return 1}和B.Tool另一个方法,如public int tool(){return 0}我怎样才能确定我打电话给我真正想要的功能?

谢谢大家!

4 个答案:

答案 0 :(得分:3)

三个选项:

危险的方式:确保您真正想要的类在类路径中首先出现,并且涉及的每个类加载器都按此顺序处理它们。这可能会非常容易打破非常混乱的结果。您无法访问该类的多个版本,您只能控制您获得的版本。不要这样做。

复杂的方式:为您依赖的每个项目创建类加载器,并使用特定的类加载器来加载类。要做到这一点需要做很多工作,你可以使用OSGI。只有在您的主要目的是了解班级装载机时才这样做。

简单正确的方法:重构您的项目,以便每个项目中的所有包都具有包名称中的项目名称(或其某种表示形式)。这使得每个包名都是唯一的,您可以毫无问题地访问类(如果您必须在一个地方使用多个工具类,可能使用完全限定的类名)当您使用它时,您也可以将工具类重命名为实际上描述了目的,类和包名称,如“Util”,“Tool”或“Misc”真的是非常糟糕的代码味道。

答案 1 :(得分:1)

可能使用user-defined class loader

  

每个用户定义的类加载器都是一个子类的实例   抽象类ClassLoader。应用程序使用用户定义的类   加载器为了扩展Java Virtual的方式   机器动态加载,从而创建类。用户自定义   类加载器可用于创建源自的类   用户定义的来源。例如,可以跨类下载一个类   网络,动态生成或从加密文件中提取。

答案 2 :(得分:1)

我认为不可能做你想做的事。如果你有三个类都叫做“src.tool.Tools”,那么Java并不关心你加载它们的jar文件。如果所有三个项目(我假设它们都是jar文件)具有相同的类,那么Java将发生冲突,您无法预测它将加载哪些工具。

确保调用正确的方法的唯一方法是确保其他两个不在类路径中。

您的问题有一个黑客解决方案。您可以为每个项目创建一个新的ClassLoader,并向ClassLoader询问Tools类所需的项目。然后使用反射,您可以实例化它并调用该方法。由于每个项目都在自己的ClassLoader中,因此三个Tools类不会再发生冲突。

前:

URLClassLoader a = new URLClassLoader(aJar.toURL(), getClass().getClassLoader());  
Class toolsClass = Class.forName("src.tool.Tools", true, a);  
Method m = toolsClass.getDeclaredMethod("tool");  
Object i = toolsClass.newInstance();  
Object result = m.invoke(instance);  

(从How should I load Jars dynamically at runtime?拉出URLClassLoader示例)

答案 3 :(得分:0)

假设您的项目A,B,C各自具有不同的包命名空间,例如com.you.A,com.you.B等,您的Tools类现在可以在多个位置使用,例如com.you.A.tool.Tools,com.you.B.tool.Tools等。

因此,在项目Z中创建Tools类的实例时,可以在声明对象引用变量时指定要使用的确切类。

private com.you.A.tool.Tools toolsFromA;
private com.you.B.tool.Tools toolsFromB;

调用toolsFromA.tool()将返回1,调用toolsFromB.tool()将返回0.