我正在使用反射发现满足某些条件的方法并调用找到的方法。
检查以下代码。使用Groovy ..
class TestClass<T>{
T hello(){
return null
}
}
class TestSubClass extends TestClass<List<String>>{
List<String> hello(){
return null
}
}
TestSubClass.methods.each{
if(it.name.contains("hello")){
println it.toGenericString()
}
}
打印出来
public java.util.List<java.lang.String> TestSubClass.hello() // <-- most relevant method for a user of this class
public java.lang.Object TestSubClass.hello()
public java.lang.Object TestSubClass.super$2$hello()
Java反射基于继承/泛型返回相同方法的多个声明,这是可以理解的。
就我而言,我想发现具有最合适签名的方法,包括returnTypes的确切类型。例如,在上面的示例中,输出中的第一个方法具有完整签名,这是我们通常调用的方法(没有反射)。
注意:上面是一个简化的例子。真正的逻辑不是基于命名来寻找方法。
答案 0 :(得分:1)
Java规范要求使用一种方法来标记合成,如果它没有在源代码中明确显示。
Java编译器发出的构造必须标记为合成if 它不对应于显式声明的构造或 隐含在源代码中,除非发出的构造是一个类 初始化方法(JVMS§2.9)。
您可以尝试:
TestSubClass.methods.each{
if(it.name.contains("hello") && !m.isSynthetic()){
println it
}
}
您还可以检查该方法是否已桥接。这是一个类似的概念: https://stackoverflow.com/a/5007394/1754020
答案 1 :(得分:1)
编译器生成其他2种方法。幸运的是,您可以查看以下属性:synthetic
:
TestSubClass.declaredMethods.each{
if(it.name.contains("hello") && !it.synthetic) {
println it.toGenericString()
}
}
现在只打印:
public java.util.List<java.lang.String> test.TestSubClass.hello()
答案 2 :(得分:0)
在我的情况下,我想以最合适的方式发现这种方法 签名,包括确切类型的退货类型。
如果它是您想知道的Java API,那么您将要查看课程public static <D extends DateSerial<?>> DateSerial.Config<D> obtainMetadata(Class<D> cls) {
Method exe = Stream.of(cls.getDeclaredMethods())
.filter(m -> m.getParameterCount() == 0 &&
m.getReturnType() == DateSerial.Config.class)
.filter(m -> {
int mod = m.getModifiers();
return Modifier.isStatic(mod) && Modifier.isPublic(mod);
})
.findFirst()
.orElseThrow(() -> new IllegalArgumentException(
"No metadata accessor for " + cls.getName()));
:
:
}
。它包含大量允许您查询类型的反射方法。
例如,以下代码片段搜索在提供的类型上声明的所有方法,用于以下方法:不带参数,String[]
和{{1}},并且返回类型为{{1 }} ...
{{1}}
您可以根据需要精确地进行审讯。例如,您可以根据具有一定数量参数的方法过滤方法,最后一个是{{1}}数组等等。警告经理:Java反射代码冗长,丑陋,并且可能很难读取。