刚开始学习并了解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"));
}
必须为它捕获例外但有效。
答案 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)
。但这甚至比实例/演员解决方案更加丑陋,而且肯定要慢得多。