oct*_*pod 9 java generics lambda
我这里有一个Handler类,它应该处理Event某种类型的s:
public interface Handler<E extends Event>
{
public void handle(E event);
@SuppressWarnings("unchecked")
public default Class<E> getEventType()
{
for(Method method: this.getClass().getDeclaredMethods())
{
if(method.getName().equals("handle")) return (Class<E>)method.getParameterTypes()[0];
}
throw new NullPointerException("Couldn't find the 'handle' method in this handler.");
}
}
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,默认情况下,它会尝试通过在执行时Event返回方法的第一个参数类型来获取类型(而不是显式返回它).这适用于以下JUnit测试:handle()getEventType()Handler
public static class EmptyEvent extends Event
{
public void test() { }
}
public static Handler<EmptyEvent> genericHandler = new Handler<EmptyEvent>()
{
@Override
public void handle(EmptyEvent event)
{
}
};
@Test
public void testEventGenerics()
{
//prints the name of EmptyEvent
System.out.println(genericHandler.getEventType());
}
Run Code Online (Sandbox Code Playgroud)
Intellij IDEA告诉我,我可以简化genericHandler为lambda表达式,所以我这样做:
public static class EmptyEvent extends Event
{
public void test() { }
}
public static Handler<EmptyEvent> genericHandler = event -> { };
@Test
public void testEventGenerics()
{
//prints the name of the base Event class
System.out.println(genericHandler.getEventType());
}
Run Code Online (Sandbox Code Playgroud)
但是,测试打印出的名称Event,而不是EmptyEvent.
所以我的问题是,有没有办法明确定义lambda表达式的泛型参数类型?
我尝试过做这样的事情,但它没有做任何事情(也是一个错误)
public static Handler<EmptyEvent> genericHandler = (EmptyEvent)event -> { };
Run Code Online (Sandbox Code Playgroud)
是的,您可以定义lambda表达式参数的类型:
public static Handler<EmptyEvent> genericHandler = (EmptyEvent event) -> { };
Run Code Online (Sandbox Code Playgroud)
通常,由于上下文暗示它是没有必要的。但是,这通常会使代码更易于阅读。
有关更多详细信息,请参见https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.27