[英]Is there a way to avoid the constructor passing the Class?
考慮這個HashMap擴展(如果它為null,則在調用“get”時生成V類的實例)
public class HashMapSafe<K, V> extends HashMap<K, V> implements Map<K, V>{
private Class<V> dataType;
public HashMapSafe(Class<V> clazz){
dataType = clazz;
}
@SuppressWarnings("unchecked")
@Override
public V get(Object key) {
if(!containsKey(key)){
try {
put((K)key, dataType.newInstance());
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return super.get(key);
}
}
它的用法是這樣的
Map<String,Section> sections = new HashMapSafe<String,Section>(Section.class);
sections.get(sectionName); //always returns a Section instance, existing or new
在我看來,兩次提供“部分”一次多余,一次作為通用類型,並且還提供它的類。 我認為這是不可能的,但是有沒有實現HashMapSafe,(保持相同的功能)所以它可以像這樣使用?
Map<String,Section> sections = new HashMapSafe<String,Section>();
或者像這樣?:
Map<String,Section> sections = new HashMapSafe<String>(Section.class);
正如其他人已經指出的那樣,由於類型擦除,你無法改善構造函數的使用,但是你應該能夠通過使用靜態工廠方法而不是構造函數來提高詳細程度......
我不是在編譯器前面,我在第一次嘗試時永遠無法獲得方法類型參數,但它會像這樣......
public static <K,V> Map<K,V> create( Class<V> cl )
{
return new HashMapSafe<K,V>(cl);
}
...
Map<String,Section> sections = HashMapSafe.create(Section.class);
不,沒有。 Java沒有Reified泛型 。
然而, Guava在MapMaker#makeComputingMap()
風格方面有一個很好的解決方案
Map<String, Integer> numbers = new MapMaker().makeComputingMap(new Function<String, Integer>() {
public Integer apply(String key) {
return 0;
}
});
當密鑰不存在時,設置並返回0
而不是null
(並且它是線程安全的,而不是您的解決方案)。
兩者都不可能。 第一個需要能夠做一些像new V()
和無法完成的事情。 第二個需要能夠在運行時設置V
類型,因為它在構造函數中傳遞,這也是無法完成的。 請記住,泛型只用於編譯時,它們會在運行時被刪除。
我發現這篇文章很有趣: 反映了泛型
簡而言之:
public abstract class AbstractUserType<T> implements UserType {
...
public Class returnedClass {
ParameterizedType parameterizedType =
(ParameterizedType) getClass().getGenericSuperClass();
return (Class) parameterizedtype.getActualTypeArguments()[0];
}
...
}
有沒有辦法避免構造函數傳遞類?
簡而言之,沒有。
根本原因是“類型擦除”。 在運行時,HashMapSafe的實現沒有隱含的與類型參數對應的類型的知識。 該信息被刪除 。 如果您需要實現知道類型是什么,則需要將其作為與Class<V>
兼容的Class
對象傳遞。
Map<String,Section> sections = new HashMapSafe<String,Section>();
由於類型擦除,這不起作用; 往上看。
Map<String,Section> sections = new HashMapSafe<String>(Section.class);
這不起作用,因為Java語言要求您在使用該語法時為所有類型參數指定類型(或通配符)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.