Mam tu Handler
klasę, która ma obsługiwać Event
s pewnego typu:Czy istnieje sposób jawnego zdefiniowania typowego parametru parametru w wyrażeniu lambda?
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.");
}
}
Jak widać, będzie starał domyślnie dostać rodzaj Event
wracając pierwszy typ parametru metody handle()
za każdym razem, gdy wykonywany jest getEventType()
(w przeciwieństwie do Handler
, który zwraca go jawnie). To działa prawidłowo z poniższego testu JUnit:
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());
}
IntelliJ IDEA mówi mi, że mogę uprościć genericHandler
do wyrażenia lambda, więc mogę to zrobić:
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());
}
Jednak wydruki przetestować nazwą z Event
, a nie EmptyEvent
.
Moje pytanie brzmi: Czy istnieje sposób wyraźnego zdefiniowania ogólnego typu parametru wyrażenia lambda?
Próbowałem zrobić coś takiego, ale to nic nie robi (również jest to błąd)
public static Handler<EmptyEvent> genericHandler = (EmptyEvent)event -> { };
HMM. Kompiluje i to odpowiada na pytanie, ale z jakiegoś powodu 'genericHandler.getEventType()' nadal zwraca nazwę 'Event'. Czy masz jakiś pomysł, dlaczego? – octopod
@Octopod prawdopodobnie dlatego, że polegasz na tym, że różne metody zwracają 'getDeclaredMethods', co jest nie-nie. – immibis
@immibis z wyjątkiem tego, że jestem pewien, że istnieje tylko jedna metoda 'handle()' (ta którą zdefiniowałem), nie ma tam? Czy mówisz, że jest też 'uchwyt (Event)'? – octopod