通过反射和使用Class.cast()进行投射

时间:2012-01-18 22:37:03

标签: java reflection casting

  

可能重复:
  Java Class.cast() vs. cast operator

我试图找出Class.cast()做了什么或者它有什么好处,但是我没有成功,同时我想知道我是否能以某种方式通过反射投射一个物体。

首先,我认为下面的某些内容可能有误,但是:

Object o = "A string";
String str = Class.forName("java.lang.String").cast(object);

但如果没有明确的演员,它就行不通。

那么cast类的Class方法有用吗?它是否有可能只是通过反射来投射对象,所以你找到对象的类,在它上面使用Class.forName并以某种方式投射它?

4 个答案:

答案 0 :(得分:29)

一个可行的例子:

class Favorites {
    private Map<Class<?>, Object> map = new HashMap<Class<?>, Object>();

    public <T> T get(Class<T> clazz) {
        return clazz.cast(map.get(clazz));
    }

    public <T> void put(Class<T> clazz, T favorite) {
        map.put(clazz, favorite);
    }
}

允许你写:

Favorites favs = new Favorites();
favs.put(String.class, "Hello");
String favoriteString = favs.get(String.class);

您的代码不起作用的原因是Class.forName()返回Class<?>,即表示未知类型的类对象。虽然编译器可能会在您的示例中推断出类型,但它通常不能。考虑:

Class.forName(new BufferedReader(System.in).readLine())

这个表达的类型是什么?很明显,编译器无法知道运行时类名是什么,所以它不知道是否

String s = Class.forName(new BufferedReader(System.in).readLine()).cast(o);

是安全的。因此它要求明确的演员。

答案 1 :(得分:5)

Class.forName的返回类型为Class<? extends Object>。您需要Class<? extends String>,例如使用String.class

String str = String.class.cast(object);

不太有用,直到您开始用某种接口类型替换String

无论如何,反思通常是邪恶的。

答案 2 :(得分:3)

您可以避免发出警告,例如使用以下代码:

public <T> T getObject(Class<T> type){
  Object o = getSomeObject();
  if (type.isInstance(o)){
     return type.cast(o);
  } else {
     return null;
  }
}

以下代码会发出警告:

public <T> T getObject(){
  return (T) getSomeObject();
}

答案 3 :(得分:2)

Class.forName将返回Class<?>类型对象。 cast方法将返回Class的类型参数。因此,在这种情况下,它会返回一个? (对象)类型对象。

你应该尝试:

Class<String> strClass = (Class<String>) Class.forName("java.lang.String");
String str = strClass.cast(object);

另见Class.cast()