Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java: How do you enforce a class type parameter to be the same as generic type specified in a generic method?

Tags:

java

generics

I created a NotificationManager class, which let's you register a generic listener to some generic notification service. In the NotificationManager class I have a generic method for registering a listener with a service:

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

So, for some INotificationListener of a particular type I'd like to force the user, when calling this method, to specify the same type as the listener. The type maps to all the INotificationListeners of the same type, however this method doesn't enforce what I'm trying to enforce. For example, I could call:

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

and the code compiles fine. What I thought this would enforce is the following:

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

Any ideas on how to accomplish this?


Update:

Sorry for the mixup, the above does in fact work. The method in the same class which does not work is actually the following:

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

And calling:

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

Does not cause a compilation error, which is what I would like it to do.

like image 201
Christopher Perry Avatar asked Jun 01 '11 20:06

Christopher Perry


1 Answers

I figured this out. I changed the signature of:

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

to:

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

where INotification is some interface that wraps the data I'm trying to return in the notification. This enforces that the class type must exactly match the notification type so that the underlying map that maps the notifications sends the messages to the registered listeners correctly without worry of programmer error.

like image 135
Christopher Perry Avatar answered Oct 05 '22 23:10

Christopher Perry