我正在尝试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) 我有一个通用的功能界面:
@FunctionalInterface
public interface Feeder<T extends Animal> {
void feed(T t);
}
Run Code Online (Sandbox Code Playgroud)
还有一些bean为不同的Animal子类实现了这个接口.
@Configuration
public class Config {
@Bean
public Feeder<Dog> dogFeeder() {
return dog -> dogService.feedDog(dog);
}
@Bean
public Feeder<Cat> catFeeder() {
return cat -> catService.feedCat(cat);
}
}
Run Code Online (Sandbox Code Playgroud)
现在已经为这些bean注入了一个服务类,并给出了一个实例Animal
.如何确定使用正确的Feeder bean?
@Service
public class PetStore {
@Autowired
private List<Feeder<? extends Animal> feeders;
private void feed(Animal animal) {
//TODO: How to determine the correct feeder from feeders?
Feeder<? extends Animal> correctFeeder = ....
correctFeeder.feed(animal);
}
}
Run Code Online (Sandbox Code Playgroud)
我试过的事情:
我最初认为我可以使用如何获取泛型类型T的类实例, …
我lambdas
在这里问了一些关于Java的问题:如何解析泛型类型的lambda参数?,但这个有点不同.
我有方法签名:
public <P> void handle(Consumer<P> consumer) {
...
}
Run Code Online (Sandbox Code Playgroud)
我可以用它lambda
:
.<Integer>handle(p -> System.out.println(p * 2));
Run Code Online (Sandbox Code Playgroud)
我能以某种方式解决那个实际的泛型类型吗?我的意思是我想进入Integer.class
那个handle
方法.
顺便说一句,我可以解决这个问题:
public <P> void handle(Class<P> pClass, Consumer<P> consumer) {...}
.handle(Integer.class, p -> System.out.println(p * 2));
Run Code Online (Sandbox Code Playgroud)
但是,如果我们将lambda更改为内联实现,它看起来就不会犹太了.