1

クラスをジェネリックにすることを望んで、自家製のDAOコンテナをリフォーマットしています。を内部的に使用しArrayListて、取得したオブジェクトを格納します。

このクラスの 1 つの使用法は、コンテナーのリストをリクエスト スコープに入れます。Websphere の制限により、ジェネリックList<Foo>をリクエスト スコープに渡すことができません (Websphere は、そのままではジェネリックを処理しません)。

リファクタリングを進める場合は、をList<Foo>非ジェネリックListオブジェクトに変換/キャストする必要があります。

// Boils down to this...
List<Foo> listFoo = new FooListing().findAllFoo();
List listThings = listFoo;
request.setAttribute("listThings", listThings);

このような属化を逆転させることの意味は何ですか? この種の操作を避けるべきですか?

編集:コードスニペットは、私が説明していることを明示的に示すために冗長です..

4

5 に答える 5

3

List のコンポーネント タイプが期待されるタイプと一致する場合、問題はありません。

Java のジェネリックは、コンパイラによる型チェックにのみ使用され、実行時には影響しません。ジェネリックをサポートしていない古いライブラリを使用している場合は、ジェネリック型を無視するしかありません。このシステムは下位互換性を考慮して設計されているため、引き続き動作するはずです。

したがって、失われているのはコンパイル時の型チェックだけです (Java が 1.4 のときの状態に戻ります。つまり、型が一致する場合はすべてが機能し、そうでない場合は実行時に ClassCastExceptions またはその他の望ましくない動作が発生します)。 )。

しかし、私はあなたが書くことができると思います

request.setAttribute("listThings", listFoo);

このメソッドは、あらゆる種類のオブジェクトを受け取ります。List<Foo>リストが必要な場合でも、 (これはまだリストです) を渡すことができます。

于 2010-03-11T06:18:49.813 に答える
2

Java はジェネリックに「型消去」を使用します。これは基本的に、コンパイラがジェネリックをチェックすることを意味しますが、ランタイムはそれをすべて忘れて、単にオブジェクトのリストとして扱います。*

a を単なるリストとして扱う場合は常にList<Foo>、Bla をリストに入れないようにするためのコンパイラ チェックが行われません。そのため、呼び出すと ClassCastException が発生List<Foo>.get()し、リストに隠れている Bla であることが判明する可能性があります。ただし、これは、一部のコードで Bla をリストに追加した場合にのみ発生します。

注意しList<Foo>たくない場合は、 Foo 以外をリストに追加する可能性のあるものに List として渡した場合List<Foo>、アクセスするたびにそれを として扱わず、 Objectsandのリストとして扱います。 instanceof チェックを追加します。

*一部の情報は実行時にアクセスできますが、複雑にしないでください。

于 2010-03-11T06:25:24.057 に答える
1

ジェネリック型の「非ジェネリック」バージョンは、「生の型」と呼ばれます。

生の同等物が要求されるジェネリック型を渡すことは、通常は問題ありません。これが実際に、Java のジェネリックが (消去を使用して) そのように機能する主な理由です。「ジェネリック化された」コードとジェネリック前のコードとの間の相互運用性を有効にするためです。

注意が必要な主なことは、 aList<Foo>を要求するものにa を渡すとList、非Fooオブジェクトが に入れられる可能性があるということListです。ここで役立つコンパイル時間チェックはありません。いくつかの実行時チェックを取得します。 a を返すメソッドを使用すると aがClassCastExceptionスローされ、非 を返す必要がありFooます。List<Foo>Foo

よりフェイルファストな動作が必要な場合は、挿入時に要素のタイプをチェックする List を取得するためにList<Foo>withをラップできます。Collections.checkedList()

Fooそれ自体がジェネリック型である場合、事態はさらに複雑になります。実行時チェックは具体化された型 (つまり、ジェネリック型パラメーターが削除された型) に対してのみ行われるため、それらに aを指定して、または単に aList<Set<Bar>>を挿入すると、要素の実行時/具体化された型がいずれかの方法であるため、わかりません。.Set<Baz>SetSet

于 2010-03-11T06:33:04.760 に答える
0

まず、ジェネリックを非ジェネリック リストにキャストすることはできないため、変換する必要があります。

次に、ジェネリック リストの 2 つの主な利点は、1) すべてのオブジェクトが指定された型であることを保証すること、2) オブジェクト コレクションのメソッドに再キャストすることなく直接アクセスできることです。これにより、よりクリーンなコードを記述でき、バック アンド フォー キャストの処理サイクルを節約できます。

ただし、これらの利点のいずれも緊急に必要というわけではありません。それらを使用できない場合、パフォーマンスの違いに気付くことはありません。ただし、コードは少し面倒に見えるかもしれません。

于 2010-03-11T06:20:46.877 に答える
0

Weblogic Portal にも同様の問題があります。この場合、非ジェネリック型を使用してください。

于 2010-03-11T06:27:03.197 に答える