2011-06-01 73 views
7

我创建了一个NotificationManager类,让我们向通用通知服务注册一个通用侦听器。在NotificationManager类我有一个与服务注册监听器的一般方法:Java:如何强制类类型参数与通用方法中指定的泛型类型相同?

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

因此,对于某些特定类型的INotificationListener我想强迫用户,调用此方法时,要指定与听众相同的类型。该类型映射到相同类型的所有INotificationListener,但是此方法不强制执行我试图执行的操作。例如,我可以拨打:

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

并且代码编译正常。我认为这将强制执行如下:

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

有关如何完成此任何想法?


更新:

对不起,查询股价,上面是实际可行的。在不工作的同一类的方法实际上是这样的:

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

,并呼吁:

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

不会导致编译错误,这就是我想它做的事。

+0

什么是'NotificationServiceFactory#get()'的声明返回类型? – 2011-06-01 20:19:41

+0

这是INotificationService 。工厂拥有一个映射,它将类类型名称映射到INotificationServices。我想它应该是INotificationService ,但是如何确保用户在通过registerNotify方法中的错误类时遇到编译错误? – 2011-06-01 20:24:05

+1

我不确定,但当我尝试传递'String.class'(Eclipse Helios SR2)时,我只是得到了所需的编译错误。你真的在运行你认为你正在运行的代码吗?或者你使用的是javac还是不同的IDE? – BalusC 2011-06-01 20:37:48

回答

1

我明白了这一点。我改的签名:

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

到:

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

其中INotification是一些接口,包装我试图在通知中返回数据。这强制类类型必须与通知类型完全匹配,以便映射通知的底层映射将消息正确地发送到注册的侦听器,而不必担心程序员错误。

0

避免此问题的一种方法是使用反射并从类本身获取类型。这将避免两次提供相同类型的需要。它只会提供一个警告,是一种非泛型的用法。

您可以从实现类的接口获取泛型类型。

+0

我选择不走这条路线,因为可读性。如果一个类使用'this'作为监听器参数来注册和取消注册一堆不同类型的监听器,很难说出它正在为通知注册/注销什么。 – 2011-06-01 21:08:45

+0

它注册/取消注册它接受的通知类型。你只需要看看实现。但我同意最好做你认为最清晰,最不可能导致错误的东西。 – 2011-06-02 07:48:54

0

位置是一个对象 - 我相信它变成:

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

记得在Java中所有的物体从Object继承。

+0

我知道,但我想强制它是完全相同的类,因为在我下面有一个映射,该类将该类映射到该类的侦听器,所以如果有人向registerNotify(Location.class,this)注册,但是广播被写为broadcastNotify(Object.class,location),监听器将不会收到消息。 – 2011-06-01 21:50:45

相关问题