Кастинг через отражение и использование Class.cast()
Возможный дубликат:
Java Class.cast() против оператора трансляции
Я безуспешно пытаюсь выяснить, что делает Class.cast()
или что это может быть полезно, в то же время мне интересно, могу ли я каким-то образом передать объект через отражение.
Сначала я подумал, что что-то вроде строк ниже, возможно, сработало неправильно:
Object o = "A string";
String str = Class.forName("java.lang.String").cast(object);
Но без явного приведения он не работает.
Итак, для чего подходит cast
метод класса Class
? И как-то возможно, просто с отражением отбрасывать объекты, поэтому вы находите класс объекта, используете Class.forName
на нем и каким-то образом его качаете?
Ответы
Ответ 1
Пример, где работает:
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() возвращает a Class<?>
, то есть объект класса, представляющий неизвестный тип. Хотя компилятор может вывести тип в вашем примере, он вообще не может быть. Рассмотрим:
Class.forName(new BufferedReader(System.in).readLine())
какой тип этого выражения? Очевидно, что компилятор не может знать, что имя класса будет во время выполнения, поэтому он не знает,
String s = Class.forName(new BufferedReader(System.in).readLine()).cast(o);
безопасен. Поэтому он запрашивает явное приведение.
Ответ 2
Возвращаемый тип Class.forName
будет Class<? extends Object>
. Вы хотите Class<? extends String>
, например, используя String.class
.
String str = String.class.cast(object);
Не очень полезно, пока вы не начнете заменять String
каким-то типом интерфейса.
В любом случае отражение обычно является злым.
Ответ 3
Class.forName
вернет объект типа Class<?>
. Метод cast
вернет параметр типа класса. Таким образом, в этом случае он вернет? (Object).
Вы должны попробовать:
Class<String> strClass = (Class<String>) Class.forName("java.lang.String");
String str = strClass.cast(object);
См. также Class.cast()
Ответ 4
Вы можете избежать предупреждения, например. со следующим кодом:
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();
}