繁体   English   中英

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

[英]Java reflection, call method of the passed in object's class

刚开始学习并了解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"));
    }

必须捕获异常,但是可以。

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

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

HasSource定义getSource()方法的位置:

public interface HasSource {
    String getSource()
}

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

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

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

一种是普通的方法调用表达式,例如object.getSource() 仅当编译器知道该object属于具有getSource()方法的类时,才有可能。

在您的情况下,编译器仅知道s是通用类型T ,它是不受限制的,因此任何类(甚至Object都可以,并且编译器无法确认是否存在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") ,如果不为null,请执行m.invoke(s) 但这比instanceof / cast解决方案还要丑陋,而且肯定慢得多。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM