簡體   English   中英

Java通配符和通用方法

[英]Java wildcards and generic methods

我有一個使用Map作為字段變量的類:

private Map<String, ?> posts;

在同一個類中,我有一個通用方法:

public <T> void log(T message) {
   if (isEnabled) {
        Date time = Calendar.getInstance().getTime();
        SimpleDateFormat sdf = new SimpleDateFormat("YYYY-MM-dd HH:mm:ss:SS");
        posts.put(sdf.format(time.getTime()), message);
    }
}

但是我在posts.put語句上收到編譯器錯誤,說:

The method put(String, capture#2-of ?) in the type Map<String,capture#2-of ?> is not 
applicable for the arguments (String, T)

我對通配符和通用方法有點陌生,所以我做錯了什么?

Map<String, ?>並不意味着您可以在該映射中放入任何內容 這意味着值類別未知 但是可以是例如Foo或Bar。 而且Foo可能與任何T類型都不兼容,因此編譯器會抱怨。 請改用Map<String, Object>或將T參數設置為類級別,然后使用它參數化地圖: Map<String, T>

當您使用不受限制的通配符類型聲明Map時:

private Map<String, ?> posts;

您將無法將除null外的任何內容放入其中。 因為? 是任何類型的替代品。 基本上,你的Map是所有實例的超類型MapString任何類型的密鑰和值。 ? 可以是DateNumberCatTiger等等。

假設您的地圖是這樣實例化的:

private Map<String, ?> posts = new HashMap<String, Date>();

並且方法中的type參數推斷為String ,則put方法正在執行以下操作:

posts.put(String, String);

...因此嘗試在需要Date地方添加String類型。 當然,這將在運行時失敗。 泛型通過為此發出編譯器錯誤來避免這些問題。


您可以通過使類本身具有通用性來解決此問題,從而在方法和映射中使用相同的類型參數:

class YourClass<T> {
    private Map<String, T> posts;

    public void log(T message) {
        if (isEnabled) {
            Date time = Calendar.getInstance().getTime();
            SimpleDateFormat sdf = new SimpleDateFormat("YYYY-MM-dd HH:mm:ss:SS");
            posts.put(sdf.format(time.getTime()), message);
        }
    }
}

另外,如注釋中所述,您應該避免以time為關鍵。 由於Date#getTime()精度只有毫秒,因此,您在間隔內輸入的任何內容(以毫秒為單位)都將存儲為相同的鍵,從而覆蓋該鍵的舊值。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM