具有替代名称的类

时间:2013-11-15 16:26:23

标签: java class classloader classname

我有一个使用libary的javaprogramm,其中几乎每个新版本的包名都会改变。

我希望我的程序可以运行在多个版本的库中。我认为可以为类创建别名:

my.class.????.path -> my.class.path

我可以得到????部分通过使用class.getName()和split,我只需要一种方法告诉类加载器将类 my.class。???。path 与另一个路径链接,所以我可以使用在我的类加载器加载的类中导入me.class.path

我有一个版本,我有很多文件,使用不同的导入,我加载它们取决于使用的libaryversion,但这是使用更多的资源,我希望我的程序保持小。

我希望有人能帮助我。

利奥

1 个答案:

答案 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。否则会爆炸!