2012-03-05 28 views
4

我有一個方法toString(Object)委託轉換爲處理程序。該處理器的定義是這樣的:如何在地圖中說「這兩種泛型是相同的」?

public interface IToStringService<T> { 
    public String toString(T value); 
} 

的代碼看起來是這樣的:

// (1) How can I say that these two wildcards must in fact be the same type? 
private Map<Class<?>, IToStringService<?>> specialHandlers = Maps.newHashMap(); 

// Generic method, must accept Object (any type really) 
@Override 
public String toString(Object value) { 

    if(null == value) { 
     return "null"; 
    } 

    Class<?> type = value.getClass(); 
    if(type.isArray()) { 
     return arrayToString(value); 
    } 

    // (2) How can I get rid of this SuppressWarnings? 
    @SuppressWarnings("unchecked") 
    IToStringService<Object> handler = (IToStringService<Object>) specialHandlers.get(type); 

    if(null != handler) { 
     return handler.toString(value); 
    } 

    return value.toString(); 
} 

public <T> void addSpecialHandler(Class<T> type, IToStringService<T> handler) { 
    specialHandlers.put(type, handler); 
} 

而且一個實現看起來是這樣的:

@SuppressWarnings("rawtypes") // Can't add generics to "Class" or I get compile errors when calling DefaultToStringService.addSpecialHandler() :-(
public class ClassToStringService implements IToStringService<Class> { 

    @Override 
    public String toString(Class value) { 
     return value == null ? "null" : value.getName(); 
    } 
} 

我有幾個問題在這裏:

  1. 我該怎麼辦ŸspecialHandlers映射中的處理程序必須與用作鍵的類型相匹配?

  2. 如何在方法內部使用相同的信息來避免鑄造和@SuppressWarnings

  3. 當我更改ClassToStringService來執行IToStringService<Class<?>>時,調用addSpecialHandler(Class.class, new ClassToStringService());時出現編譯錯誤如何解決此問題?

+1

您希望強制執行該鍵的泛型與該泛型的值相同。那麼,你不能在一個地圖中做到這一點。但既然你控制着地圖的內容,你真的有這種限制嗎? – Luciano 2012-03-05 15:49:49

+0

@盧西亞諾:這麼想,但有時候,有人知道一個竅門。最後一點呢? – 2012-03-05 15:54:49

+1

[通用鍵/值與相關類型的通用映射]的可能重複(http://stackoverflow.com/questions/2208317/generic-map-of-generic-key-values-with-related-types) – 2012-03-05 16:03:29

回答

1

你不能用Java來做到這一點。我會解釋爲什麼。 ?擴展在類型理論中被稱爲存在類型,但Java具有有限的形式。 ?擴展X意味着存在Ÿ如:Y延長X.我們可以重寫Map<Class<?>, IToStringService<?>>爲:

Map<Class<(exists T1 extends Object)>, IToStringService<(exist T2 extends Object)>> 

但是,我們希望:

Map<(exists T extends Object Class<T>, IToStringService<T>> 

在Java中,我們無法用語言表達這一點,因爲存在量詞可以」在Java中明確指定。但是,在斯卡拉你可以做到這一點。

相關問題