【发布时间】:2018-06-13 20:14:26
【问题描述】:
我有一个用例,使用反射来获取Function对象的参数和返回值类型会很有用1。
但我发现 lambda 表达式导致的函数对象的令人惊讶的行为:该对象没有具有特定类型的 apply 方法。
示例代码:
import java.lang.reflect.Type;
import java.lang.reflect.Method;
import java.util.function.Function;
public class Trying {
public static void main(String[] args) {
Function<Integer, Double> lambda = i -> i.doubleValue();
Function<Integer, Double> methodRef = Integer::doubleValue;
Function<Integer, Double> anon = new Function<Integer, Double>() {
@Override
public Double apply(Integer i) {
return i.doubleValue();
}
};
printType("lambda", lambda);
printType("methodRef", methodRef);
printType("anon", anon);
}
private static void printType(String name, Function<?, ?> f) {
System.out.println("### " + name);
System.out.println("super: " + f.getClass().getSuperclass().getSimpleName());
for (Type i : f.getClass().getGenericInterfaces()) {
System.out.println("interface: " + i);
}
for (Method m : f.getClass().getDeclaredMethods()) {
System.out.println("name: " + m.getName() + ", bridge: " + m.isBridge()
+ ", arg type: " + m.getParameterTypes()[0].getSimpleName()
+ ", return type: " + m.getReturnType().getSimpleName());
}
System.out.println();
}
}
此代码打印以下内容:
### methodRef
super: Object
interface: interface java.util.function.Function
name: apply, bridge: false, arg type: Object, return type: Object
### lambda
super: Object
interface: interface java.util.function.Function
name: apply, bridge: false, arg type: Object, return type: Object
### anon
super: Object
interface: java.util.function.Function<java.lang.Integer, java.lang.Double>
name: apply, bridge: false, arg type: Integer, return type: Double
name: apply, bridge: true, arg type: Object, return type: Object
- 有没有办法解决这个问题并使用反射来获取函数对象的具体类型?
- 是语言指定的行为,还是依赖于实现?
- 为什么 lambda 和方法引用对象会以这种方式运行?
1:我想使用此信息为数据绑定 API 创建默认转换器。
【问题讨论】:
-
Related Q&A。我很确定这是故意的,而且没有解决办法。
-
这与函数或 lambda 无关。这是 java 泛型的泛型行为。了解类型擦除。
-
@gagansingh:请注意,示例代码中的匿名类具有可用的特定类型,可以使用反射进行访问。一些通用信息,例如关于具有应用类型参数的超类,存储在类文件中。例如阅读bridge methods。
-
@Lii 感谢您的链接。
-
为什么要“故意”这样做?似乎更像是一种疏忽。如果你能找到匿名类的泛型类型参数,为什么不能找到 lambdas 呢?我对这个设计决定感到失望。
标签: java reflection lambda