7 Stimmen

Java: Wie erzwingt man, dass ein Klassentyp-Parameter mit dem in einer generischen Methode angegebenen generischen Typ identisch ist?

Ich habe eine NotificationManager-Klasse erstellt, mit der man einen generischen Listener für einen generischen Benachrichtigungsdienst registrieren kann. In der NotificationManager-Klasse habe ich eine generische Methode zur Registrierung eines Listeners bei einem Dienst:

public static <E> void registerNotify(Class<E> type, INotificationListener<E> listener) {
    @SuppressWarnings("unchecked")
    INotificationService<E> service = (INotificationService<E>) NotificationServiceFactory.get(type);
    service.registerNotificationListener(listener);
}

Also, für einige INotificationListener eines bestimmten Typs möchte ich den Benutzer zwingen, beim Aufruf dieser Methode den gleichen Typ wie der Hörer anzugeben. Der Typ wird auf alle INotificationListener desselben Typs abgebildet, aber diese Methode erzwingt nicht, was ich zu erzwingen versuche. Zum Beispiel könnte ich aufrufen:

INotificationListener<Location> locationListener = this;
NotificationManager.registerNotify(String.class, locationListener);

und der Code lässt sich gut kompilieren. Ich dachte, dies würde das Folgende erzwingen:

INotificationListener<Location> locationListener = this;
NotificationManager.registerNotify(Location.class, locationListener);

Haben Sie eine Idee, wie man das erreichen kann?


Aktualisierung:

Entschuldigen Sie die Verwechslung, aber das oben genannte funktioniert tatsächlich. Die Methode in der gleichen Klasse, die nicht funktioniert, ist eigentlich die folgende:

public static <E> void broadcastNotify(Class<E> type, E data)
    {
        @SuppressWarnings("unchecked")
        INotificationService<E> service = (INotificationService<E>) NotificationServiceFactory.get(type);
        service.notifyListeners(data);
    }

Und ruft an:

Location location = new Location();
NotificationManager.broadcastNotify(Object.class, location);

Dies führt nicht zu einem Kompilierungsfehler, was ich eigentlich möchte.

1voto

Christopher Perry Punkte 38024

Ich habe das herausgefunden. Ich habe die Signatur von geändert:

public static <E> void broadcastNotify(Class<E> type, E data)

zu:

public static <E> void broadcastNotify(Class<E> type, INotification<E> data)

wobei INotification eine Schnittstelle ist, die die Daten umschließt, die ich in der Benachrichtigung zurückgeben möchte. Dadurch wird erzwungen, dass der Klassentyp genau mit dem Benachrichtigungstyp übereinstimmen muss, so dass die zugrundeliegende Map, die die Benachrichtigungen zuordnet, die Nachrichten korrekt an die registrierten Zuhörer sendet, ohne dass man sich um Programmiererfehler sorgen muss.

0voto

Peter Lawrey Punkte 511323

Eine Möglichkeit, dieses Problem zu vermeiden, ist die Verwendung von Reflexion und die Beschaffung des Typs aus der Klasse selbst. Dadurch wird vermieden, dass derselbe Typ zweimal angegeben werden muss. Es wird nur eine Warnung ausgegeben, wenn ein nicht-generischer Typ verwendet wird.

Sie können den generischen Typ aus der Schnittstelle für die implementierende Klasse erhalten.

0voto

jabbie Punkte 2450

Der Standort ist ein Objekt - ich glaube, er wird es:

public static <Object> void broadcastNotify(Class<Object> type, Object data) 

Denken Sie daran, dass in Java alle Objekte von Object erben.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X