- PR -

java1.6でのArrayListの使い方

1
投稿者投稿内容
nakagawa
会議室デビュー日: 2007/03/05
投稿数: 3
投稿日時: 2007-03-05 11:01
はじめまして。

早速ですが、
現在Java1.6でWEBアプリケーションの開発をしています。

そして、以下のようなことをしたいのです。
  1.ArrayList<Meisai>オブジェクトをセッションに格納
  2.ArrayList<Meisai>をセッションから取り出し、
    新規作成のMeisaiオブジェクトをaddする。

※MeisaiはSerializableを実装したクラスです

やり方として、以下の2パターンを試してみました。

--パターン1--
1: ArrayList list = (ArrayList)session.getAttribute("List");
2: Meisai m = new Meisai();
3: list.add(m);


--パターン2--
1: ArrayList<Meisai> list =
2: (ArrayList<Meisai>)session.getAttribute("List");
3: Meisai m = new Meisai();
4: list.add(m);

しかし、パターン1の場合は、3行目で
"警告:[unchecked] raw 型 java.util.ArrayList のメンバとしての add(E) への無検査呼び出しです。"

パターン2の場合は、1行目で
"警告:[unchecked] 無検査キャストです"

と、警告が出ます。
ArrayListの使い方がおかしいとは分かるのですが、
どのようにするのが正しいやり方なのでしょうか?

分かりにくい文章ですみませんがよろしくお願いします。
かつのり
ぬし
会議室デビュー日: 2004/03/18
投稿数: 2015
お住まい・勤務地: 札幌
投稿日時: 2007-03-05 11:52
例えばStringを含むListなら、
コード:
List<? super String> list = (List<? super String>) session.getAttribute("key");
list.add("list");


って感じでいかがでしょうか。

面倒なら、メソッドの先頭に
@SuppressWarnings("unchecked")
という注釈を付けても警告が抑制されるはずです。
(JDK6のjavacでも対応しているはず・・・)
sawat
大ベテラン
会議室デビュー日: 2006/08/02
投稿数: 112
投稿日時: 2007-03-05 13:49
使い方としてはパターン2であっていますが、
HttpSession#getValueの戻り値の型がObjectなので警告が発生してしまいます。

@SuppressWarnings("unchecked")をつければ警告は抑えられますが、@SuppressWarningsはメソッド単位なので、メソッドのほかの箇所での "unchecked" についての警告も発生しなくなってしまいます。

なので、以下のような専用のキャストメソッドを作ったほうがよいかもしれません。
コード:
@SuppressWarnings("unchecked")
public static <E> List<E> castList(Object list) {
    return (List<E>)list;
}


このメソッドを使う場合は、引数がList型であることはチェックされますが、リストの中身の型まではチェックされません。実際に中身の型が違っている場合は get を呼び出したとき ClassCastException が発生します。
nakagawa
会議室デビュー日: 2007/03/05
投稿数: 3
投稿日時: 2007-03-05 13:58
かつのりさん、sawatさん、早速の返答ありがとうございます。

Meisaiクラスは、
「public class Meisai implements Serializable」
なので、ジェネリックスは"<? super Object>"となるのでしょうか?
これで、コンパイルしてみると、
"ArrayList<? super Object> list =
(ArrayList<? super Object>)session.getAttribute("List"); "の行で、

「警告:[unchecked] 無検査キャストです」と、出てしまうのですが...


>@SuppressWarnings("unchecked")
>という注釈を付けても警告が抑制されるはずです。
こんなのがあるとは、知りませんでした。
勉強になりました、ありがとうございます。
でも、これはあくまでも警告を抑制するだけなのですよね。
根本的な解決(?)になってないような気がするのですが、
こうするしかないのですかね。。。

かつのり
ぬし
会議室デビュー日: 2004/03/18
投稿数: 2015
お住まい・勤務地: 札幌
投稿日時: 2007-03-05 14:16
当方の環境はEclipse3.2.0 + JDK6で試しましたが、
Eclipse3.2.0のJDTなら警告が出ませんね。

警告が出るのが正しいのか正しくないのか、
この辺は正直覚えていないのでハッキリいえませんが、
動きに相違があるのであれば、
コンパイラの仕様もしくはバグというケースもあると思います。

コード:
根本的な解決(?)になってないような気がするのですが、 


使用するAPIによってはGenericsに対応していない場合もありますので、
これが根本解決であると思います。
JavaのGenerics自体がコンパイラレベルでのお話で、
ランタイムに影響ある話ではないので。
nakagawa
会議室デビュー日: 2007/03/05
投稿数: 3
投稿日時: 2007-03-05 19:11
かつのりさん、返答ありがとうございます。

引用:

JavaのGenerics自体がコンパイラレベルでのお話で、
ランタイムに影響ある話ではないので。



そうなんですよね。
コンパイルエラーになるわけでもなし、
実行時エラーになるわけでもなし、
あくまでも警告と割り切れば良いのでしょうね。

ありがとうございます。
1

スキルアップ/キャリアアップ(JOB@IT)