如何从不同的jar子加载相同的类

我在两个不同的jar jar1和jar2中有一个类Client.java现在在运行时我想决定加载哪个Client.class

if (country==india){ // load Client class of jar1 ) else{ load client class from jar2 } 

我能做到吗……

如果这两个类具有相同的包名,即com.mycompany.Client,那么最终会导致加载哪个版本的Client有些随意。 它归结为首先在类路径上。 这是JAR地狱的情况http://en.wikipedia.org/wiki/Java_Classloader#JAR_hell 。

这是一个要避免的好情况,但是如果你绝对必须有同一个类的不同版本,那么有办法做到这一点。 一种方法是使用自定义类加载器,类加载器将知道您需要执行哪个版本。 这不是一件容易的事情,也很难管理。 OSGi框架是帮助管理它的另一种选择(它使用自定义类加载器),但如果你只有一个类的实例,我不会使用它,因为它是另一个需要时间和维护的框架。

底线:如果可以的话,避免这种情况,如果不能,就采取阻力最小的路径。

如果类有不同的包名,@ Casidiablo提供了一个很好的答案。

您必须使用路径的“完整”名称。 例如:

 if (country==india){ name.first.package.Client client = new name.first.package.Client(); } else{ name.second.package.Client client = new name.second.package.Client(); } 

无论如何……我会尽量避免做那样的事情……这会使你的代码难以阅读和维护。

如果你真的有两个副本,一个具有完全相同的完全限定名称的类,在两个jar子里,那么……

如果您想要安全,则不应将其中任何一个放在默认类加载器的类路径中。 您将需要创建另外两个类加载器,并在每个加载器中放入一个jar。 您将需要获取这两个类的类,并且您将需要使用reflection来创建所需的实例。

我想你有两种方法:

1)定义一个接口客户端,并实现不同的类,例如:IndiaClient和Country2Client; 然后


    接口客户端{...}
     class IndiaClient实现客户端{...}
     class Country2Client实现客户端{...}

    客户客户;
     if(country == india){
         client = new IndiaClient();
     )else {
         client = new Country2Client();
     }

2)在2个不同的jar文件中使用相同的类名继续使用,但是仍然需要一个接口或超类,并使用不同的ClassLoader来加载Client类:


    接口IClient {...}
     class Client在jar1中实现IClient {...} //
     class Client在jar2中实现IClient {...} //

     Class  clientClass;
     if(country == india){
         clientClass = classLoader1.loadClass(“package.Client”);
     )else {
         clientClass = classLoader2.loadClass(“package.Client”);
     }
     IClient client = clientClass.newInstance();

  • 至于如何获取classLoaders,可以参考JDK文档。