我在两个不同的jar jar1&中有一个Client.java类。 jar2 现在在运行时我想决定加载哪个Client.class
if (country==india){
// load Client class of jar1
) else{
load client class from jar2
}
我能做到吗......
答案 0 :(得分:7)
如果2个类具有相同的包名,即com.mycompany.Client,那么最终会导致加载哪个版本的Client有些随意。它归结为首先在类路径上。这是JAR地狱的情况http://en.wikipedia.org/wiki/Java_Classloader#JAR_hell。
这是一个要避免的好情况,但是如果你必须拥有同一个类的不同版本,那么有办法做到这一点。一种方法是使用自定义类加载器,类加载器将知道您需要执行哪个版本。这不是一件容易的事情,而且难以管理。 OSGi框架是帮助管理它的另一种选择(它使用自定义类加载器),但如果你只有一个类的实例,我就不会使用它,因为它是另一个需要时间和维护的框架。
底线:如果可以的话,避免这种情况,如果你不能,就采取阻力最小的路径。
如果这些类具有不同的包名,@ Casidiablo提供了一个很好的答案。
答案 1 :(得分:4)
您必须使用路径的“完整”名称。例如:
if (country==india){
name.first.package.Client client = new name.first.package.Client();
} else{
name.second.package.Client client = new name.second.package.Client();
}
无论如何......我会尽量避免做那样的事情......这会让你的代码难以阅读和维护。
答案 2 :(得分:3)
如果你真的有两个副本,一个具有完全相同的完全限定名称的类,在两个罐子中,那么......
如果您想要安全,则不应将 中的 放在默认类加载器的类路径中。您将需要创建另外两个类加载器,并在每个加载器中放入一个jar。您将需要为这两个类获取一个类,并且您将需要使用反射来创建您想要的实例。
答案 3 :(得分:0)
我认为你有两种方式:
1)定义一个接口客户端,并实现不同的类,例如:IndiaClient和Country2Client;然后
interface Client {...} class IndiaClient implements Client {...} class Country2Client implements Client {...} Client client; if (country==india){ client = new IndiaClient(); ) else{ client = new Country2Client(); }
2)在2个不同的jar文件中使用相同的类名继续使用,但仍需要接口或超类,并使用不同的ClassLoader加载Client类:
interface IClient {...} class Client implements IClient {...} // in jar1 class Client implements IClient {...} // in jar2 Class<IClient> clientClass; if (country==india){ clientClass = classLoader1.loadClass("package.Client"); ) else{ clientClass = classLoader2.loadClass("package.Client"); } IClient client = clientClass.newInstance();