Java类反射:使用通配符参数初始化外部类

时间:2018-07-08 20:11:50

标签: java generics reflection

我已经搜索了此问题的解决方案,为期2天,现在必须在这里提出问题:-(我的问题:

我创建了新的自定义Java类:

package my.app.test;

class Test extends Object {
    Test(){

    }

    public void print(){
        System.out.println("success");
    }
}

在另一个包裹中,我有:

package my.app.test2;

public class Test2 {
    Test2(Class<? extends Object> Test){

    }

    public void execute(Class<? extends Object> Test){

    }
}

现在我想用Test.class作为参数的on来膨胀Test2.class:

package my.app.test;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class Index {
    Index(){}

    static public void inflate(){
        ClassLoader loader = Thread.currentThread().getContextClassLoader();
        if(loader != null)
            try {
                Class<?> Test2 = Class.forName("my.app.test2.Test2", false, loader);
                if(Test2 != null){
                    Class<?>[] types = new Class[1];
                    types[0] = Test.class;
                    Method m = Test2.getDeclaredMethod("execute", types);
                    m.setAccessible(true);
                    try {
                        m.invoke(Test.class, new Test());
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    } catch (InvocationTargetException e) {
                        e.printStackTrace();
                    }
                }
            } catch (NoSuchMethodException | ClassNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
    }
}

但是我得到了错误:

java.lang.NoSuchMethodException: my.app.test2.Test2.execute(my.app.test.Test)

如果可能的话?

3 个答案:

答案 0 :(得分:1)

您的Test2类没有类似execute(Test)的方法,但是具有execute(Class)。您应该执行Test2.getDeclaredMethod("execute", Class.class)

答案 1 :(得分:0)

在您必须使用Object作为类型的情况下,在运行时将删除通用类型。有关详细信息,请参见Java Type Erasure,有关该主题的详细说明,请参见Baeldung

答案 2 :(得分:0)

感谢大家提供有用的提示!我已经更改和改进了代码,添加了注释以更好地理解。

my.app.test.Test.java

package my.app.test;

public class Test extends Object {
    public String string = "Hello! ";
    public Test(String value){
        string += value;
    }

    public Test(){

    }

    public void print(){
        System.out.println(string);
    }
}

my.app.test.Index.java

package my.app.test;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class Index {
    Index(){}

    static public void inflate(){
        ClassLoader loader = Thread.currentThread().getContextClassLoader();
        if(loader != null){
            try {
                Class<?> Test2 = Class.forName("my.app.test2.Test2", false, loader);
                if(Test2 != null){

                    Class<?>[] types = new Class[1];
                    types[0] = Object.class;
                    // Get method public void execute(Object object){}
                    Method m = Test2.getDeclaredMethod("execute", types);
                    m.setAccessible(true);
                    try {
                        // Invoke Test.class as Object
                        m.invoke(Test2.getDeclaredConstructor().newInstance(), new Test("It works!"));
                    } catch (InvocationTargetException | InstantiationException | IllegalAccessException e) {
                        e.printStackTrace();
                    }

                    types = new Class[1];
                    types[0] = Class.class;
                    // Get method public void execute(Class<? extends Object> Test){}
                    m = Test2.getDeclaredMethod("execute", types);
                    m.setAccessible(true);
                    try {
                        // Invoke Test.class as Class
                        m.invoke(Test2.getDeclaredConstructor().newInstance(), Test.class);
                    } catch (InvocationTargetException | InstantiationException | IllegalAccessException e) {
                        e.printStackTrace();
                    }
                }
            } catch (NoSuchMethodException | ClassNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
}

my.app.test2.Test2.java

package my.app.test2;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class Test2 {
    public Test2(){

    }

    public void execute(Object Test){
        System.out.println("public void execute(Object object){}");
        ClassLoader loader = Thread.currentThread().getContextClassLoader();
        if(loader != null){
            try {
                // Get method public void print(){}
                Method m = Test.getClass().getDeclaredMethod("print");
                m.setAccessible(true);
                try {
                    // Invoke Test.class with String parameter initialized inside Index
                    m.invoke(Test);
                } catch (InvocationTargetException | IllegalAccessException e) {
                    e.printStackTrace();
                }
            } catch (NoSuchMethodException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }

    public void execute(Class<? extends Object> Test){
        System.out.println("public void execute(Class<? extends Object> test){}");
    }
}