Видимо этот специальный код для использования
шаблон делает возврат
getFromSessionMap тип переменной и
следовательно, нет необходимости в приведении.
По сути, должно быть типизацией где-то между получением результата session.getAttribute(sessionKey)
и присвоением MyClassType
. Язык Java (и JVM) не позволит некоторому объекту, который не является экземпляром MyClassType
(или его подтипом), быть назначенным переменной MyClassType
.
Независимо от того, как вы пишете код, должна произойти трансляция типа . И поскольку атрибут (по-видимому) не является MyClassType
(или подтипом), вы получаете ClassCastException
.
Итак, настоящий вопрос в том, почему вы не получаете ошибку компиляции? И ответ - @SuppressWarnings("unchecked")
! Если вы удалите это предупреждение, вы получите сообщение об ошибке «небезопасное преобразование типов» для этой строки:
return (T) session.getAttribute(sessionKey);
По правде говоря, Java не может выполнять приведение (реального) типа к универсальному типу. И это то, на что должно указывать предупреждение / сообщение об ошибке. Фактически, после того, как код скомпилирован, этот код
public <T> T getFromSessionMap(String sessionKey) {
return (T)session.getAttribute(sessionKey);
}
на самом деле не отличается по смыслу от этого:
public Object getFromSessionMap(String sessionKey) {
return session.getAttribute(sessionKey);
}
Технически это называется "стирание типа".
Так где же на самом деле происходит проверка типов / типовых трансляций? Ответ в этой строке:
MyClassType type = request.getFromSessionMap("abc");
Даже если вы не написали здесь приведение типов, код, сгенерированный компилятором Java, выполняет преобразование типов перед присвоением значения type
. Он должен. Потому что, насколько ему известно, экземпляр, который он назначает, может быть любой тип объекта.
Другие авторы предложили добавить аргумент класса к getFromSessionMap
. Само по себе это абсолютно ничего не делает . Если вы также замените тело метода на:
return clazz.cast(session.getAttribute(sessionKey));
вы заставите метод действительно проверять тип. Но это только заставляет ClassCastException
быть брошенным в другом месте. И оператор присваивания все равно будет выполнять приведение скрытого типа !!