簡體   English   中英

使用匿名類創建參數化類型對象

[英]Creating parameterized type object using anonymous class

這可能是一個愚蠢的問題,但我剛剛看到一個問題,詢問如何為泛型 type 創建一個 Type 變量 共識似乎是你應該有一個返回該類型的虛擬方法,然后使用反射來獲取它(在這種情況下他想要Map<String, String> )。 像這樣的事情:

public Map<String, String> dummy() { throw new Error(); }

Type mapStringString = Class.forName("ThisClass").getMethod("dummy").getGenericReturnType();

我的問題是,沒有那么多使用反射,你不能做這樣的事情:

Type mapStringString = new ParameterizedType() {
    public Type getRawType() {
        return Map.class;
    }

    public Type getOwnerType() {
        return null;
    }

    public Type[] getActualTypeArguments() {
        return new Type[] { String.class, String.class };
    }
};

這行得通嗎? 如果沒有,為什么不呢? 如果確實如此,會有哪些危險/問題(除了能夠返回某些類型,如Integer<String>這顯然是不可能的。

當然可以,而且對於大多數應用程序來說,這可能就足夠了。

但是,使用第一種方法,您可以獲得更精致的對象。 例如,假設您使用第一種方法創建對象type1 ,使用第二種方法創建對象type2 然后type1.equals(type2)將返回 true(因為第一個方法返回一個正確實現 equals 方法的對象)但type2.equals(type1)將返回 false(因為在第二個方法中,您沒有覆蓋 equals -method,並且正在使用Object的實現)。

同樣的推理適用於其他(有時有用的方法),例如toStringhashCode等。第二種方法不提供這些的有用實現。

如果您的項目中包含 Google 的Guava庫(您應該這樣做;它很棒),請使用它的TypeToken來獲取類型。 Google 的Gson庫(用於與 JSON 交互)有一個類似的版本 兩者都像這樣使用(獲取表示List<String>Type

Type t = new TypeToken<List<String>>(){}.getType();

如果您不想依賴任何第三方庫,您仍然可以使用匿名類型通過一行代碼獲得通用的具體類型(這種技術不適用於接口,並且可能比 Abstract 的價值更麻煩類型)。 要獲取表示HashMap<String, String>Type ,請執行以下操作:

Type t = new HashMap<String, String>(){}.getClass().getGenericSuperclass();

我已經驗證生成的Type實例.equals()是由GsonTypeToken創建的Type實例,但尚未驗證Guava版本的TypeToken ,我目前無法訪問。 (Guava 是一個更通用的庫,它對各種事情都非常方便,無論如何你都應該使用它。)

實際上,我認為最簡單的方法(==最少代碼)是一個擴展您感興趣的類型的虛擬接口,然后從它的類中獲取getGenericInterfaces()[0] getGenericSuperclass()如果您感興趣,請使用getGenericSuperclass()一類):

private interface MapStringString extends Map<String, String> {}
private static ParameterizedType mapStringString(){
    return (ParameterizedType) MapStringString.class.getGenericInterfaces()[0];
}

但是,它不能很好地擴展,因為您必須為要表示的每個ParameterizedType創建一個新類。 我不明白為什么你的實現不會做(除非在某處有縮小強制轉換),而且它確實有一個吸引人的好處,你可以使它可重用。

除了上面提到的來自 Google 的庫之外,還有一個來自 Apache 的庫可以完成這項工作。

import org.apache.commons.lang3.reflect.TypeUtils;
...
ParameterizedType type = TypeUtils.parameterize(List.class, Double.class);
...

在GitHub上FINDE代碼在這里和Maven的文物在這里

暫無
暫無

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

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