我正在尝试Java 8中的新Lambdas,我正在寻找一种方法来使用lambda类的反射来获得lambda函数的返回类型.我特别感兴趣的是lambda实现了一个通用的超接口.在下面的代码示例中,MapFunction<F, T>是通用的超接口,我正在寻找一种方法来找出绑定到泛型参数的类型T.
虽然Java在编译器之后丢弃了许多泛型类型信息,但是泛型超类和通用超接口的子类(和匿名子类)确实保留了该类型信息.通过反射,可以访问这些类型.在下面的例子(情况1) ,反射告诉我,所述MyMapper的实施MapFunction结合java.lang.Integer到一般类型参数T.
即使对于本身是通用的子类,也有一些方法可以找出与泛型参数绑定的内容,如果已知其他一些参数.考虑壳体2在下面的例子中,IdentityMapper其中两个F和T结合到相同的类型.当我们知道这一点时,F如果我们知道参数类型T(在我的例子中,我们知道),我们知道类型.
现在的问题是,如何才能实现Java 8 lambdas的类似功能?由于它们实际上不是通用超接口的常规子类,因此上述方法不起作用.具体来说,我可以计算出的parseLambda结合java.lang.Integer来T,而identityLambda结合同向F和T?
PS:理论上应该可以反编译lambda代码,然后使用嵌入式编译器(如JDT)并进入其类型推断.我希望有一个更简单的方法来做到这一点;-)
/**
* The superinterface.
*/
public interface MapFunction<F, T> {
T map(F value);
}
/**
* Case 1: A non-generic subclass.
*/
public class MyMapper implements MapFunction<String, Integer> {
public Integer map(String value) …Run Code Online (Sandbox Code Playgroud) 我读过Brian Goetz的一些评论,可序列化的lambdas"与不可序列化的lambda相比,具有明显更高的性能成本".
我现在很好奇:这究竟是什么开销和导致它的原因?它是仅影响lambda的实例化,还是仅影响调用?
在下面的代码中,两种情况(callExistingInstance()和callWithNewInstance())都会受到"MyFunction"的可串行性的影响,还是仅受第二种情况的影响?
interface MyFunction<IN, OUT> {
OUT call(IN arg);
}
void callExistingInstance() {
long toAdd = 1;
long value = 0;
final MyFunction<Long, Long> adder = (number) -> number + toAdd;
for (int i = 0; i < LARGE_NUMBER; i++) {
value = adder.call(value);
}
}
void callWithNewInstance() {
long value = 0;
for (int i = 0; i < LARGE_NUMBER; i++) {
long toAdd = 1;
MyFunction<Long, Long> adder = (number) -> number + toAdd;
value = …Run Code Online (Sandbox Code Playgroud)