我有一个使用libary的javaprogramm,其中几乎每个新版本的包名都会改变。
我希望我的程序可以运行在多个版本的库中。我认为可以为类创建别名:
my.class.????.path -> my.class.path
我可以得到????部分通过使用class.getName()和split,我只需要一种方法告诉类加载器将类 my.class。???。path 与另一个路径链接,所以我可以使用在我的类加载器加载的类中导入me.class.path 。
我有一个版本,我有很多文件,使用不同的导入,我加载它们取决于使用的libaryversion,但这是使用更多的资源,我希望我的程序保持小。
我希望有人能帮助我。
利奥
答案 0 :(得分:0)
或者至少它不是那么琐碎/明智。 看看这个非常简单的Java程序:
import java.util.Random;
public class Simple {
public static void main(String[] args) {
Random r = new Random();
System.out.println(r.nextInt());
}
}
使用javac Simple.java
会产生以下.class
文件(javap -c Simple
):
Compiled from "Simple.java"
public class Simple {
public Simple();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: new #2 // class java/util/Random
3: dup
4: invokespecial #3 // Method java/util/Random."<init>":()V
7: astore_1
8: getstatic #4 // Field java/lang/System.out:Ljava/io/PrintStream;
11: aload_1
12: invokevirtual #5 // Method java/util/Random.nextInt:()I
15: invokevirtual #6 // Method java/io/PrintStream.println:(I)V
18: return
}
正如您所看到的,类名是完全限定的,因此如果不使用库ASM来操作字节码,您将无法更改它们。
但,可能:
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class Simple {
public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
Class cl = Class.forName("java.util.Random");
Object r = cl.newInstance();
Method nextIntMethod = cl.getMethod("nextInt");
int randomInt = (Integer) nextIntMethod.invoke(r);
System.out.println(randomInt);
}
}
虽然这种方式真的很麻烦。
请注意,使用反射的解决方案从2个重要行增加到5个。 此外,您仍然需要按版本获取FQCN。否则会爆炸!