どうやら、テンプレートを使用するためのこの特別なコードにより、 getFromSessionMap の戻り値が変数型になるため、キャストは必要ありません。
基本的に、の結果の取得と への代入の間のどこかに型キャストが必要です。Java 言語 (および JVM)では、インスタンス (またはそのサブタイプ)ではないオブジェクトを変数に割り当てることはできません。session.getAttribute(sessionKey)
MyClassType
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
。それはしなければなりません。知る限り、割り当てているインスタンスは任意のオブジェクト型である可能性があるためです。
他の投稿者は、 Class 引数を に追加することを提案していますgetFromSessionMap
。それ自体では、これはまったく何もしません。メソッドの本体も次のように置き換える場合:
return clazz.cast(session.getAttribute(sessionKey));
メソッドが実際に実際の型チェックを行うようにします。しかし、これClassCastException
は別の場所に投げられるだけです。そして、割り当てステートメントはまだ隠し型キャストを行います!!