问题
I'm trying to use custom Class as a value in a Map<String, Class<?>>
. Following are relevant parts of code:
Following is declaration and initialization of Map in 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);
}
Now I'm using this map to typecast an object to one of these classes: (assume that all classes contain a method getName()
which return a String
)
String name = (
(
mapQuery2ResponseType.get("string1")
)obj1
).getName();
where, obj1
is of generic type T
,
but it's not allowing me to do so and says: Syntax error on token "obj1", delete this token
.
Please help me to understand where am I doing wrong?
Edit:
When I use following code, it worked perfectly giving me the expected result,
String name = (
(
CustomClass1
)obj1
).getName();
and obj1
is of the same type as returned by mapQuery2ResponseType.put("string1", CustomClass1.class);
.
Here I can see 1 thing... if I use use it directly, i use it as "CustomClass1"
, whereas if I get it from map by mapQuery2ResponseType.get("string1")
, it returns "CustomClass1.class"
. I'm not sure if there is any difference in these two approaches? If there is, what is it?
So actually there wont be any conversion, it's just that I'm using it for large number of classes, and so trying to use a generalized approach.
Edit2:
as given in this question: Java: difference between “CustomClass1” and “CustomClass1.class”?, I think, reflection is the only solution for this task. But can anybody explain how to do it using reflection?
回答1:
Simply put, this is syntactically invalid code. Not coincidentally, the compiler is telling you exactly what the problem is.
Remove ob1
. I don't know what it is, or what you think it's supposed to do, but it does not make any sense there. To explain this, I'm going to twiddle your code just a bit:
The original code:
String name = ((mapQuery2ResponseType.get("string1"))obj1).getName();
Now with a local variable:
Class<?> clazz = mapQuery2ResponseType.get("string1");
String name = ((clazz) obj1).getName();
Okay, so now I think I see: you're trying to use a Class
instance to cast an object. You can't do this – Java's syntax simply does not permit it. Here's how a cast might normally look:
Object foo = "bar";
String baz = (String) foo;
Note how the token for the cast expression is String
, not String.class
.
Class#cast() might look like a useful alternative, but that's not going to be of any use here, since you've only got Class<?>
, and not Class<T>
.
Forget about the Map
. I suggest you restructure your code entirely such that the getName()
method is defined on an interface which obj1
and all similar objects implement (assuming that the various objects have heterogenous types).
For example:
interface MyCommonInterface {
String getName();
}
class MyClass implements MyCommonInterface {
public String getName() {
// snip
}
}
// ...
MyClass obj1 = /* ... */
String name = obj1.getName();
No casting, no fancy Map
s or Class
instances. Just proper, simple use of the right parts of the language.
回答2:
I think its better to use JAVA Reflection to do that.
Typecast needs the Type syntax befor the object to be cast, so you can do like this (CustomClass1.class)obj1, but you can't do it like (mapQuery2ResponseType.get("string1"))obj1 cause compiler can't take the cast in runtime environment.
When compile your code, you map value is considered as a value not a valid type, so you can't make cast like you have showed.
来源:https://stackoverflow.com/questions/15583567/java-using-classes-as-a-value-in-hashmap