Java反射,传入对象类的调用方法

时间:2018-01-09 18:25:43

标签: java reflection

刚开始学习并了解java反射,非常感谢有关此问题的任何帮助。

我试图编写一个方法,它看起来像这样:

    private <T> void myMethod (List<T> testSub) {
        testSub.forEach(s -> assertEquals(s.getSource(), "TEST"));
    }

但它显示错误,因为java不知道testSub的类是否有getSource()这个方法,并且它希望我将s.getSource()强制转换为已知类。

我想要的是以某种方式让java知道testSub类中的itmes具有这个getSource()方法,并且可以调用它并且可以安全地调用它。

提前致谢!

----------------------------更新------------------ ---- 选择使用这种方式:

    private <T> void myMethod (List<T> testSub, Class<T> clazz) {

        testSub.forEach(s -> assertEquals(clazz.getMethod("getSource").invok(s), "TEST"));
    }

必须为它捕获例外但有效。

2 个答案:

答案 0 :(得分:1)

为类型变量定义添加一个绑定:

private <T extends HasSource> void myMethod (List<T> testSub) {

其中HasSource定义getSource()方法:

public interface HasSource {
    String getSource()
}

编译器会知道T实际上是HasSource的子类,因此它具有getSource()方法。

当然,要利用此解决方案,您需要将要用作testSub元素的所有类实现HasSource接口。

答案 1 :(得分:0)

您可以通过两种方式调用getSource()方法。

一个是正常方法调用表达式,如object.getSource()。只有当编译器知道object属于具有getSource()方法的类时,才有可能。

在您的情况下,编译器只知道s属于通用类型T,它是无界的,所以可以是任何类,甚至Object,编译器可以&# 39;确认有一个getSource()方法。

如果您没有具有getSource()方法的列表元素的公共父类或接口,则可以使用instanceof / cast组合。如果你真的知道可能的元素类,那可能对你有用。

for (T s : testSub) {
    if (s instanceof Class1) {
        assertEquals(((Class1) s).getSource(), "TEST"));
    } else if (s instanceof Class2) {
        assertEquals(((Class2) s).getSource(), "TEST"));
    } else {
        throw new IllegalArgumentException();
    }
}

另一种方式是使用反射。您可以找到Method m = s.getClass.getMethod("getSource"),如果不是空,则可以找到m.invoke(s)。但这甚至比实例/演员解决方案更加丑陋,而且肯定要慢得多。