2011-06-01 102 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

相關問題