在java中反思并尝试复制控制器/操作

时间:2013-12-18 00:04:58

标签: java reflection

有没有办法只根据字符串名实例化一个类?我理解反射需要包名称o完全限定名称。但如果你得到了:

/类名/方法名?参数= X

你把它撕成了类似的东西:

callClass(ClassName).callMethod(methodName).params(...)(在这种情况下.params()用于方法)

在php中这非常容易。我理解这在Java中非常容易,因为docs state需要类的完全限定名称 - 因为包允许您多次定义单个名称,并且这种方法可能会导致一些严重的性能的问题。

我有什么想法可以实现这样的目标

2 个答案:

答案 0 :(得分:1)

无论如何,您需要一个完全限定的类名。

您可以按惯例执行此操作 - 将您的类名附加到预定的包名称(或假设默认包)

或者,您可以执行一些类加载器魔术来查找基于部分名称的完整类名(假设名称不含糊)。换句话说,您的类加载器将跟踪所有已加载的类,然后您可以使用您的部分名称匹配这些类名。但是,对于大多数应用程序来说,这是非常难以理解的。

答案 1 :(得分:0)

正如之前回答的@DNA,你总是需要一个完全限定的类名。然后是反射,它既真的很慢,也很痛苦。以Guava为例,你可以这样做:

public static void main(String[] args) throws Exception {
    String myClassName = "App";
    String methodName = "method";
    Object[] params = {};
    ClassPath cp = ClassPath.from(ClassLoader.getSystemClassLoader());
    ImmutableSet<ClassPath.ClassInfo> cls = cp.getTopLevelClasses();

    for (ClassPath.ClassInfo cl : cls) {
        if(cl.getSimpleName().equals(myClassName)) {
            Class<?> clazz = cl.load();
            for (Method m : clazz.getMethods()) {
                if(m.getName().equals(methodName)) {
                    Object instance = clazz.newInstance();

                    // invoke method - prints Hello
                    m.invoke(instance, params);
                }
            }
        }
    }
}

public void method() {
    System.out.println("Hello!!!");
}

非常残暴。抛出很多你需要处理的例外。如果你有一个更大的项目,使用这样的东西需要很长时间。