Кастинг через отражение и использование Class.cast() - программирование
Подтвердить что ты не робот

Кастинг через отражение и использование Class.cast()

Возможный дубликат:
Java Class.cast() против оператора трансляции

Я безуспешно пытаюсь выяснить, что делает Class.cast() или что это может быть полезно, в то же время мне интересно, могу ли я каким-то образом передать объект через отражение.

Сначала я подумал, что что-то вроде строк ниже, возможно, сработало неправильно:

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

Но без явного приведения он не работает.

Итак, для чего подходит cast метод класса Class? И как-то возможно, просто с отражением отбрасывать объекты, поэтому вы находите класс объекта, используете Class.forName на нем и каким-то образом его качаете?

4b9b3361

Ответ 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();
}