映射值的Java泛型
我想在下面的场景中直接转换为适当的列表类型。如果擦除杀死了类类型信息,那么在下面的场景中维护类类型的最佳方法是什么映射值的Java泛型,java,generics,Java,Generics,我想在下面的场景中直接转换为适当的列表类型。如果擦除杀死了类类型信息,那么在下面的场景中维护类类型的最佳方法是什么 class MyProperties { private final Map<String, List<?>> properties = new HashMap<>(); public void put(final String key, final List<?> value) { propert
class MyProperties {
private final Map<String, List<?>> properties = new HashMap<>();
public void put(final String key, final List<?> value) {
properties.put(key, value);
}
public <T> List<T> get(final String key, final Class<T> t) {
final List<?> object = properties.get(key);
// Here is where the issue lies because the class type is gone, so we
// will always skip this block and return null
if (object.getClass().isAssignableFrom(t)){
return (List<T>)object;
}
return null;
}
public static void main(String[] args){
List<String> myList = new ArrayList<>();
myList.add("Bacon");
myList.add("Eggs");
List<Integer> myList2 = new ArrayList<>();
myList2.add(1);
myList2.add(2);
MyProperties props = new MyProperties();
props.put("myKey", myList);
props.put("myKey2", myList2);
// I'd like to directly cast to the appropriate list type if possible
List<String> foo = props.get("myKey", String.class);
List<Integer> foo2 = props.get("myKey2", Integer.class);
}
}
类属性{
私有最终映射对象=properties.get(key);
//这就是问题所在,因为类类型已经不存在了,所以我们
//将始终跳过此块并返回null
if(object.getClass().isAssignableFrom(t)){
返回(列表)对象;
}
返回null;
}
公共静态void main(字符串[]args){
List myList=new ArrayList();
myList.添加(“培根”);
myList.添加(“鸡蛋”);
List myList2=new ArrayList();
myList2.添加(1);
myList2.添加(2);
MyProperties props=新的MyProperties();
道具放置(“myKey”,myList);
道具放置(“myKey2”,myList2);
//如果可能的话,我想直接转换为适当的列表类型
List foo=props.get(“myKey”,String.class);
List foo2=props.get(“myKey2”,Integer.class);
}
}
存储元素类型
public <T> List<T> get(final String key, final Class<T> t) {
Class<?> propClass = propClasses.get( key );
if( propClass == null || t == null || !t.equals( propClass ) ) {
return null;
}
return (List<T>)properties.get(key);
}
您可以做的是同时传递列表元素的类,并将其单独存储:
private final Map<String, List<?>> properties = new HashMap<>();
private final Map<String, Class<?>> propClasses= new HashMap<>();
public <T> void put(final String key, final List<T> value, final Class<T> elementClass) {
properties.put(key, value);
propClasses.put(key, elementClass);
}
检索具有确切元素类型的列表
public <T> List<T> get(final String key, final Class<T> t) {
Class<?> propClass = propClasses.get( key );
if( propClass == null || t == null || !t.equals( propClass ) ) {
return null;
}
return (List<T>)properties.get(key);
}
检索元素类型为下限的列表(只读)
如果要使用元素类的超类,可以更改get()
方法或添加“只读”方法,如下所示:
public <T> List<? extends T> getReadOnly(final String key, final Class<T> t) {
Class<?> propClass = propClasses.get( key );
if( propClass == null || t == null || !t.isAssignableFrom( propClass ) ) {
return null;
}
return (List<? extends T>)properties.get(key);
}
存储元素类型
public <T> List<T> get(final String key, final Class<T> t) {
Class<?> propClass = propClasses.get( key );
if( propClass == null || t == null || !t.equals( propClass ) ) {
return null;
}
return (List<T>)properties.get(key);
}
您可以做的是同时传递列表元素的类,并将其单独存储:
private final Map<String, List<?>> properties = new HashMap<>();
private final Map<String, Class<?>> propClasses= new HashMap<>();
public <T> void put(final String key, final List<T> value, final Class<T> elementClass) {
properties.put(key, value);
propClasses.put(key, elementClass);
}
检索具有确切元素类型的列表
public <T> List<T> get(final String key, final Class<T> t) {
Class<?> propClass = propClasses.get( key );
if( propClass == null || t == null || !t.equals( propClass ) ) {
return null;
}
return (List<T>)properties.get(key);
}
检索元素类型为下限的列表(只读)
如果要使用元素类的超类,可以更改get()
方法或添加“只读”方法,如下所示:
public <T> List<? extends T> getReadOnly(final String key, final Class<T> t) {
Class<?> propClass = propClasses.get( key );
if( propClass == null || t == null || !t.isAssignableFrom( propClass ) ) {
return null;
}
return (List<? extends T>)properties.get(key);
}
您正试图使用泛型方法签名强制执行类型完整性。但它显然会在编译后被擦除(类型擦除) 因此,您需要将类型实际存储为对象。这样,编译后类型信息不会丢失
因为每个键需要存储一个类型,所以数据结构的明显选择是额外的
Map您试图使用泛型方法签名来强制类型完整性。但它显然会在编译后被擦除(类型擦除)
因此,您需要将类型实际存储为对象。这样,编译后类型信息不会丢失
由于每个键需要存储一种类型,数据结构的明显选择将是额外的映射。在许多其他问题中,object.getClass()
将返回一个基于列表的类,因为object
是一个列表
。。。它永远不会从字符串
或整数
中赋值,这与类型擦除无关。是的,没错。这是我一直坚持的部分,因为我认为一定有更好的方法来实现这一点。我不想将列表包装在一个跟踪列表及其类型的新类中。还要记住,class
有一个方法。在许多其他问题中,object.getClass()
将返回一个基于List
的类,因为object
是一个List
。。。它永远不会从字符串
或整数
中赋值,这与类型擦除无关。是的,没错。这是我一直坚持的部分,因为我认为一定有更好的方法来实现这一点。我不想把列表包装成一个新的类来跟踪列表和它的类型还记得class
有一个方法。谢谢你的建议。非常彻底!谢谢你的建议。非常彻底!