[英]How to call the static class method for a generic object?
我需要將泛型類傳遞給類的構造函數。 類是SpiceRequest從RoboSpice的Android庫來構造參考。
看起來奇怪的是,類需要將泛型類傳遞給contstructor,當它可以從泛型類本身訪問時,在這種情況下是RESULT.class
,但也許我錯了。 無論如何,我不打算改變庫的代碼,而是需要使用泛型類型的SpiceRequest
, Map<String, ? extends Object>
SpiceRequest
Map<String, ? extends Object>
。 這是我的代碼:
SpiceRequest<Map<String, ? extends Object>> request =
new SpiceRequest<Map<String, ? extends Object>>(???) {
...
};
和SpiceRequest
構造函數的簽名:
public SpiceRequest(final Class<RESULT> clazz) {
...
}
對於??? 我曾嘗試Map.class
與編譯器錯誤: The constructor SpiceRequest<Map<String,? extends Object>>(Class<Map>) is undefined.
The constructor SpiceRequest<Map<String,? extends Object>>(Class<Map>) is undefined.
Map<String, ? extends Object>.class
Map<String, ? extends Object>.class
給出了錯誤: Syntax error on tokens, PrimitiveType expected instead
,特別是下划線? extends Object
? extends Object
。 它也提供與Map.class
相同的錯誤。
和Map.<String, ? extends Object>class
Map.<String, ? extends Object>class
給出了相同的編譯器錯誤。
獲取泛型類Class<Map<String, ? extends Object>>
,?的正確方法是什么Class<Map<String, ? extends Object>>
Class<Map<String, ? extends Object>>
?
具體參數化類型或通配符參數化類型沒有類文字。 來自Angelika Langer的泛型教程 :
通配符參數化類型在名為type erasure的進程中轉換為字節代碼時會丟失其類型參數。 作為類型擦除的副作用,泛型類型的所有實例化共享相同的運行時表示,即相應原始類型的表示 。 換句話說,參數化類型沒有自己的類型表示。 因此,沒有必要形成類文字,例如
List<?>.class
,List<? extends Number>.class
List<? extends Number>.class
和List<Long>.class
,因為不存在這樣的Class
對象。 只有原始類型List
有一個表示其運行時類型的Class
對象。 它被稱為List.class
。
由於相同的原因,具體的參數化類型沒有類文字,簡而言之就是類型擦除 。
為了您的目的,您只需要對類文字進行未經檢查的強制轉換:
Class<Map<String, ?>> c = (Class<Map<String, ?>>)(Class<?>)Map.class;
請注意,通過Class<?>
進行雙重轉換是必要的,因為從Class<Map>
到Class<Map<String, ?>>
的直接轉換是非法的。
這個問題與RoboSpice本身並沒有關系,而是與Java語法的限制有關:沒有一個可以用來獲取Java中參數化泛型類的類/類型的文本。
如果你想做點什么
public class ListTweetRequest extends SpiceRequest<List<Tweet>> {
public ListTweetRequest(Object cacheKey ) {
super( <Here is the problem>, cacheKey );
}
}
那么你不能將類List<Tweet>.class
傳遞給你的父構造函數。 這實際上是一個Java限制,因為泛型是使用類型擦除和List<Tweet>.class
在Java中沒有實際意義。
最好和最干凈的工作是使用中間類型,如:
public class ListTweet extends List<Tweet> {
}
public class ListTweetRequest extends SpiceRequest<ListTweet> {
public ListTweetRequest(Object cacheKey ) {
super( ListTweet.class, cacheKey );
}
}
這樣做的好處是可以為您提供一個可以傳遞給SpiceRequest構造函數的實際類型。 但要注意混淆。 在這種情況下,proguard將嘗試刪除ListTweet類,您必須明確地保護它免於混淆。
我總是猜測擦除,但你試過用Map.class調用它嗎?
我也遇到了這個問題,我找到了像@Snicolas這樣的解決方案。
看看這個robospice-sample-retrofit的例子:
實際上最好不繼承原始的List接口,而是繼承任何子類,如ArrayList等,否則你將不得不實現所有的接口方法。
import java.util.ArrayList;
public class Contributor {
public String login;
public int contributions;
@SuppressWarnings("serial")
public static class List extends ArrayList<Contributor> {
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.