如何从不同的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 {...} // ClassclientClass; if(country == india){ clientClass = classLoader1.loadClass(“package.Client”); )else { clientClass = classLoader2.loadClass(“package.Client”); } IClient client = clientClass.newInstance();
- 至于如何获取classLoaders,可以参考JDK文档。