Абсолютно незачем писать Foo.class.cast(o)
, это эквивалент (Foo)o
.
В общем, если X
является реифицируемым типом и Class<X> clazz
, то clazz.cast(o)
совпадает с (X)o
.
Если все типы реифицируемы, метод Class.cast()
будет избыточным и бесполезным.
К сожалению, из-за стирания в текущей версии Java не все типы реифицируемы. Например, переменные типа не могут быть преобразованы.
Если T
является переменной типа, приведение (T)o
не отмечено флажком, поскольку во время выполнения точный тип T
неизвестен JVM, JVM не может проверить, действительно ли o
является типом T
. Приведение может быть разрешено ошибочно, что может вызвать проблемы позже.
Это не большая проблема; обычно, когда программист делает (T)o
, он уже рассудил, что приведение безопасно и не вызовет никаких проблем во время выполнения. Приведение проверяется логикой приложения.
Предположим, что Class<T> clazz
доступен в точке приведения, тогда мы действительно знаем, что T
во время выполнения; мы можем добавить дополнительную проверку времени выполнения, чтобы убедиться, что o
действительно T
.
check clazz.isInstance(o);
(T)o;
И это, по сути, то, что делает Class.cast()
.
Мы ни в коем случае не ожидаем, что приведение типов завершится неудачно, поэтому в правильно реализованном приложении проверка clazz.isInstance(o)
всегда должна завершаться успешно, поэтому clazz.cast(o)
эквивалентно (T)o
- опять же, в предположении, что код правильный.
Если можно доказать, что код правильный и приведение безопасно, можно было бы предпочесть (T)o
clazz.cast(o)
по соображениям производительности. В примере MutableClassToInstanceMap
, поднятого в другом ответе, мы, очевидно, видим, что приведение безопасно, поэтому простого (T)o
было бы достаточно.
person
irreputable
schedule
26.10.2011