Java generics: capture kann nicht angewendet werden, - Objekt
Ich habe code, der eine Map
von (Message)Handler. Ich bin versucht zu machen, den Handler generified (wie gesehen, durch die interface-Prozedur). Ohne Generika Handler, die alle brauchen, um zu Gießen aus dem Objekt der jeweiligen Klasse, das wäre schön, zu vermeiden (aber alles funktioniert). Für jede Nachrichtenklasse (Foo
unten) ich habe eine handler-Klasse.
Wie kann ich eine Karte von jeder Art von Klasse, um jede Art von Handler und Holen/rufen Sie "nur" mit einem Object
? (die parameter handleMessage(Object)
können nicht eingeschränkt werden)
Sehen MWE unten.
import java.util.*;
public class Logic
{
Map<Class<?>, Handler<?>> handlers = new HashMap<Class<?>, Handler<?>>();
public void run()
{
handlers.put(Foo.class, new FooHandler());
}
public void handleMessage(Object msg)
{
Handler<?> handler = handlers.get(msg.getClass());
if (handler != null) {
handler.execute(msg);
}
}
private interface Handler<T>
{
public void execute(T msg);
}
private class FooHandler implements Handler<Foo>
{
public void execute(Foo msg) {}
}
private class Foo {}
}
Dieser code erzeugt:
Logik.java:16: execute(capture#x ?) in der Logik.Handler kann nicht angewendet werden, > to (java.lang.Objekt)
handler.ausführen(msg);
Wie kann das repariert werden, zu arbeiten, während immer noch halten die Handler-Schnittstelle generischen?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Kann man nicht definieren, die Beziehung zwischen Schlüssel und Wert in einem Feld, aber Sie können accessor Methoden zu erzwingen, sofern nur diese Methoden verwendet werden, um auf die Karte.
Das problem ist, dass
execute()
nimmt einen bestimmten parameter-Typ, dass ist genauer alsObject
.Jedoch in Ihrer
handleMessage()
Methode, die der compiler nicht weiß, welche Art der parameter. Angenommen, ein Fall, woFooHandler
ist registriert für KlasseBar
(die möglich wäre).In diesem Zusammenhang
handler.execute(msg);
würde tatsächlich dazu führenFooHandler#execute(Foo)
genannt wird, mit einemBar
argument, das Ergebnis wäre einClassCastException
(es sei dennBar extends Foo
). Damit der compiler weigert sich zu kompilieren, der code.Andere Antwort, die war nicht hier, aber es sollten - entfernen Sie alle generics-syntax (d.h. entfernen Sie alle
<?>
). Dann wird der parser wieder JDK1.4 syntax und das wird alles gut funktionieren.