8

ここでジェネリックの問題に直面しています。以下のステートメントで私が見逃していることを誰か教えてもらえますか?

1.

warning: [unchecked] unchecked conversion

List<Question> qList = (List) session.getAttribute("qList");
                                       ^
  required: List<Question>
  found:    List

2.

warning: [unchecked] unchecked conversion

List<ExamSchedule> eList = new <ExamSchedule>ArrayList();

required: List<ExamSchedule>
found:    ArrayList

警告を抑制したくありません。任意の提案をいただければ幸いです。

4

4 に答える 4

10
List<Question> qList = (List) session.getAttribute("qList");
  1. session.getAttribute("qList");タイプのインスタンスを返しますObject。したがって、明示的にキャストする必要があります。

  2. (List)は単なる生の型でList<String>あり、ジェネリック型であるため、生の型をジェネリック型参照にキャストしようとすると警告が表示されます。

今、これを行うと:

List<Question> qList = (List<Question>) session.getAttribute("qList");

List<String>キャストは実行時チェックですが、実行時に型が消去されるため、実際には aとetc.の間に違いはありList<Foo>ません。したがって、そのエラーが発生します。この型変換は、保持されている型を気にせずに(List<?> list)、オブジェクトが であることを検証します。List

List<ExamSchedule> eList = new <ExamSchedule>ArrayList();

これは構文エラーArrayList<ExamSchedule>です<ExamSchedule>ArrayList

提案:

List<?> qList = (List<?>) session.getAttribute("qList");
List<ExamSchedule> eList = new ArrayList<ExamSchedule>();
于 2013-05-10T05:01:11.163 に答える
5

答え 1:

List<Question> qList = (List<Question>) session.getAttribute("qList");

答え 2:

List<ExamSchedule> eList = new ArrayList<ExamSchedule>();

Genericsの概念をまず把握します。

最初の答えについては、を使用している場合、次のようHttpSessionにステートメントに注釈を付けずに警告を落ち着かせることはできません。@SuppressWarnings

@SuppressWarnings("unchecked")
List<Question> qList = (List<Question>) session.getAttribute("qList");

これは、Objectfromを返すサーブレット API によるものHttpSession.getAttribute()です。それ以外の場合、コンパイラはタイプ セーフ (チェックされていない from からObjectへのキャストList<Question>) について警告します。

于 2013-05-10T05:01:57.713 に答える
3

Java には具体化されたジェネリックはありません。リストは、実行時にその要素の型を保持しません。したがって、制限付きの型にキャストしようとすると、警告が表示されます。型を知っていると思うかもしれませんが、コンパイラはそれが間違っている可能性があることを思い出させます。

バインドされていないコレクションにキャストしてから、個々の要素の型を確認できます

List<?> tmp = (List<?>) session.getAttribute("qList");
if (tmp != null) {
  for (Object o : tmp) {
    Question q = (Question) o;
    /* Use q ... */
  }
}

一部の API に を渡す必要がある場合はList<Question>、要素をループ内で正しく宣言された新しいリストにコピーできます。明らかに、これはユーティリティ メソッドに含める必要がある多くの混乱です。しかし、柔軟にするために、おそらく動的型キャストを使用したいと思うでしょう。

public static <T> List<T> asList(Collection<?> c, Class<? extends T> type) {
  if (c == null)
    return null;
  List<T> list = new ArrayList(c.size());
  for (Object o : c)
    list.add(type.cast(o));
  return list;
}

List<Question> qList = asList((Collection<?>) session.getAttribute("qList"), Question.class);

java.util.Collectionsには、必要なことをほぼ実行するメソッドがあります。残念ながら、元のラップされたコレクション内の要素の型はチェックされません。また、新しい独立したコレクションを作成するのではなく、基になるコレクションをラップするため、型エラーが発生する可能性があります。

幸いなことに、2 番目の質問は簡単です。

List<ExamSchedule> eList = new ArrayList<>();
于 2013-05-10T05:35:32.937 に答える