题目描述
自定义的FunctionInterface,lambda 写法反射获取方法时泛型信息被擦除,直接实现该接口可以正确获得泛型类型。
题目来源及自己的思路
Java function
猜测1:lambda写法的直接实现了 CFunction<T> 顶级接口,造成缺失子接口PersonFunction的泛型信息
相关代码
package com.example.test;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;
public class TestLambda {
public static void main(String[] args) throws Exception {
invoke(personFunctionImpl());
invoke(personFunction());
}
public static void invoke(PersonFunction personFunction)
throws InvocationTargetException, IllegalAccessException {
Class<? extends PersonFunction> lambdaClass = personFunction.getClass();
System.out.println("methods: " + Arrays.toString(lambdaClass.getDeclaredMethods()));
Method accept;
try {
accept = lambdaClass.getMethod("accept", Person.class);
accept.invoke(personFunction, new Person("java"));
} catch (NoSuchMethodException e) {
System.out.println(e);
}
}
public static PersonFunction personFunction() {
return System.out::println;
}
public static PersonFunction personFunctionImpl() {
return new PersonFunction() {
@Override
public void accept(Person person) {
System.out.println(person);
}
};
}
}
@FunctionalInterface
interface CFunction <T> {
void accept(T t);
}
class Person {
String name;
public Person(String name) {
this.name = name;
}
@Override
public String toString() {
return name;
}
}
interface PersonFunction extends CFunction<Person> {}
你期待的结果是什么?实际看到的错误信息又是什么?
运行日志:
methods: [public void com.example.test.TestLambda$1.accept(com.example.test.Person), public void com.example.test.TestLambda$1.accept(java.lang.Object)]
java
methods: [public void com.example.test.TestLambda$$Lambda$1/303563356.accept(java.lang.Object), private static com.example.test.PersonFunction com.example.test.TestLambda$$Lambda$1/303563356.get$Lambda(java.io.PrintStream)]
java.lang.NoSuchMethodException: com.example.test.TestLambda$$Lambda$1/303563356.accept(com.example.test.Person)
测试代码输出可以看到实现类有具体类型的方法,以及泛型接口的Object参数方法,lambda表达式实现的方法只有一个 Object参数的方法。
理论上两种写法应该是同一种行为,为何会有如此大的差距,给编写框架造成很大困扰。有没有好的实践方式求大佬指点。
其实有点没太看懂题主想要表达的意思,如果仅仅是为了获取泛型类型,那你这种情况就是
Type
体系下的ParameterizedType
,也就是一种参数化类型那获取就很简单直接了