[英]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.