Java:使用Classes作为hashmap中的值

时间:2013-03-23 05:02:07

标签: java class hashmap syntax-error

我尝试将自定义类用作Map<String, Class<?>>中的值。以下是代码的相关部分:

以下是main()中的地图声明和初始化:

public static Map<String, Class<?>> mapQuery2ResponseType = new HashMap<String, Class<?>>();
static {
    mapQuery2ResponseType.put("string1", CustomClass1.class);
    mapQuery2ResponseType.put("string2", CustomClass2.class);
    mapQuery2ResponseType.put("string3", CustomClass3.class);
}

现在我使用此映射将对象类型转换为其中一个类:(假设所有类都包含一个返回getName()的方法String

String name = (
                  (
                       mapQuery2ResponseType.get("string1")
                  )obj1
              ).getName();

其中,obj1属于通用类型T

但它不允许我这样做并说:Syntax error on token "obj1", delete this token

请帮助我了解我在哪里做错了?

Edit:

当我使用下面的代码时,它完美地给了我预期的结果,

String name = (
                  (
                       CustomClass1
                  )obj1
              ).getName();

obj1 mapQuery2ResponseType.put("string1", CustomClass1.class);返回的类型相同

在这里,我可以看到一件事...如果我使用它直接使用它,我将其用作"CustomClass1",而如果我通过mapQuery2ResponseType.get("string1")从地图获取它,则返回"CustomClass1.class" 。我不确定这两种方法有什么不同吗?如果有,那是什么?

所以实际上不会有任何转换,只是我将它用于大量的类,因此尝试使用通用方法。

Edit2:

在这个问题中给出:Java: difference between “CustomClass1” and “CustomClass1.class”?,我认为,反射是这项任务的唯一解决方案。但任何人都可以解释如何使用反射来做到这一点吗?

2 个答案:

答案 0 :(得分:5)

简单地说,这是语法上无效的代码。并非巧合,编译器告诉你完全问题是什么。

删除ob1。我不知道它是什么,或者你认为它应该做什么,但它没有任何意义。为了解释这一点,我将稍微改变你的代码:

原始代码:

String name = ((mapQuery2ResponseType.get("string1"))obj1).getName();

现在有一个局部变量:

Class<?> clazz = mapQuery2ResponseType.get("string1");
String name = ((clazz) obj1).getName();

好的,现在我想我明白了:您正在尝试使用Class实例来投射对象。你不能这样做 - Java's syntax simply does not permit it.以下是演员通常看起来的样子:

Object foo = "bar";
String baz = (String) foo;

请注意投射表达式的标记是String,而不是String.class

Class#cast()可能看起来像一个有用的替代方案,但这不会有任何用处,因为你只有Class<?>而不是Class<T>

忘掉Map。我建议您完全重构代码,以便在getName()和所有类似对象实现的接口上定义obj1方法(假设各种对象具有异构类型)。

例如:

interface MyCommonInterface {
    String getName();
}

class MyClass implements MyCommonInterface {
    public String getName() {
        // snip
    }
}

// ...
MyClass obj1 = /* ... */
String name = obj1.getName();

没有强制转换,没有花哨的MapClass个实例。恰当,简单地使用语言的正确部分。

答案 1 :(得分:-2)

我认为最好使用JAVA Reflection来做到这一点。

Typecast需要类型语法befor要转换的对象,所以你可以这样做(CustomClass1.class)obj1,但你不能这样做(mapQuery2ResponseType.get(“string1”))obj1导致编译器可以在运行时环境中进行演员表。

编译代码时,map值被视为一个非有效类型的值,因此你不能像你所展示的那样进行转换。