2013-06-28 41 views
1

我在Java项目中遇到问题,我有一堆项目(例如A,B,C ...),它们碰巧有一个Tools类在诸如src.tool.Tools之类的路径中的工具文件夹中,所有这些路径和路径名称都相同。调用与包名相同的其他函数的函数

现在,我的项目Z在其构建路径中包含了所有这些项目(A,B,C ...)。我如何确保当我导入一个工具类时,我正在导入我真正需要的工具类?如果在A.Tool中,我有一个方法,如公共int工具(){返回1}和在B.Tool另一种方法,如公共int工具(){返回0}我怎样才能确保我称之为我真正想要的功能?

谢谢大家!

+0

我不认为你可以用class来控制是否使用。这由类路径中的jar文件的顺序决定。 (提供该类的第一个jar文件将被使用。) – aioobe

+0

您需要确保包名称是唯一的,比如'a.tool','b.tool'等等,而不是每个包名都相同项目。 –

+1

这似乎是一个非常糟糕的设计,导致方法(不是函数)具有***完全相同的名称。你应该看看用更好的名字来重命名它们,而不是所有这些诡计。 –

回答

3

三个选项:

的冒险方式:确保那么你真的想通过这门课是第一位在classpath和涉及的每个类加载器按照该顺序处理它们。由于结果非常混乱,这可能会非常容易中断。你无法访问该课程的多个版本,你只能控制你获得的。不要这样做。

复杂的方式:为您所依赖的每个项目创建类加载器,并根据特定类加载器来加载该类。为了得到正确的结果,需要做很多工作,您可能可以使用OSGI。只有当您的主要目标是了解班级装载机时才这样做。

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

+0

看来重构是解决这个问题最简单的方法,它不会在将来给很多麻烦。谢谢! – Random

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()将可能使用user-defined class loader返回0

+0

对不起,我写得不好,我没有解释得很好。问题是它们具有相同的包名称空间。例如在Jar AI中有com.you.tool.Tools和Jar BI中有com.you.tool.Tools – Random

+0

_假设你的项目A,B,C各有不同的包名称空间_那么,它们不会** – BackSlash

1

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

+0

哇!那是一大堆文件。谢谢! – Random

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); 

(URLClassLoader的例子来自How should I load Jars dynamically at runtime?拉)

+0

是的,你说得对,项目意味着罐子。对不起,我正在用日食术语思考错误的命名。 – Random

相关问题