英文:
Java Generics : Retrieving the type from a generic object
问题
我有一个通用类 Class1<K, V>,它接受两种类型。现在我想要维护一个将 String 映射到 Class1 对象的映射,即 Map<String, Class1>。当我遍历 Map 时,我能够获取每个 Class1 对象的类型 (K, V) 吗?
也就是说,让我们将代码想象成如下:
Map<String, Class1> map;
map.put("1", Class1<String, Integer> obj1);
map.put("2", Class1<String, Double> obj2);
map.put("3", Class1<Integer, Double> obj3);
现在,当我遍历该映射时,我能否以某种方式获取每个 Class1 对象的类型 (K, V)?
英文:
I have a generic class Class1<K, V> which takes two types. Now I want to maintain a map which maps String to Class1 objects i.e Map<String, Class1> . Can I retrieve the types (K,V) of each Class1 Object while I iterate through Map?
i.e lets think of code as below
Map<String, Class1> map;
map.put("1", Class1<String, Integer> obj1);
map.put("2", Class1<String, Double> obj2);
map.put("3", Class1<Integer, Double> obj3);
Now when I iterate over the map ... Can I somehow get the types(K, V) of each Class1 object??
答案1
得分: 1
根据JVM规范,这是不可能的。
泛型类型仅在编译时可用。在运行时,它们只是Object
类型。
你只有两个选项:
- 为你的对象添加类定义变量,并在需要这些信息时使用它。
- 例如,对于
List<Object>
以及其他集合,如果不为空,你可以从中获取一个项目并调用item.getClass()
。
附注: 顺便说一下,你的方法不正确,不能解决这个问题。你可以实现一个接口,类似于:
interface TypeConverter {
boolean isValid(String str); // 在转换之前调用它,检查当前转换器是否适用于所需的转换
Class1 converts(String str); // 调用它进行转换
}
对于每种所需的类型,你都需要创建单独的转换器(这是策略模式)。你的最终代码可能如下所示:
final List<TypeConverter> converters = new ArrayList<>();
converters.add(new OneTypeConverter());
converters.add(new TwoTypeConverter());
public static Class1 convert(String str) {
for (TypeConverter converter : converters) {
if (converter.isValid(str)) {
return converter.convert(str);
}
}
throw new RuntimeException("找不到合适的转换器");
}
英文:
It's not possible according to JVM specification.
Generic types are available only at compile time. At runtime ther're only Object
.
All you have is 2 options:
- Add class definition variable to your objects and us it when you need this info.
- E.g. for
List<Object>
as well as for other collections if it's not empty, you can get an item from it and getitem.getClass()
.
P.S. Buy the way, your approach is not correct to solve this issue. You could implement an interface like:
interface TypeConverter {
boolean isValid(String str); // call it before to check if current converter valid for required transform or not
Class1 converts(String str); // call it to convert
}
And for each required types you have to create separate converter (this is Strategy Pattern). And your final code could look like this:
final TypeConverter converters = new ArrayList<>();
converters.add(new OneTypeConverter());
converters.add(new TwoTypeConverter());
public static Class1 convert(String str) {
for(TypeConverter convereter : converters)
if(converter.isValid(str))
return converter.convert(str);
throw new RuntimeException("No suitable converter found");
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论