2

ソースコードがわからないライブラリを使用しているとしましょう。次のように、リストを返すメソッドがあります。

public List<SomeObj> getObjs() { ... }

これが良い考えかどうか疑問に思っています:

ArrayList<SomeObj> objs = (ArrayList<SomeObj>) getObjs();

たとえば、getObjs() 内の List の具体的な実装が である場合、LinkedList何らかの型の不一致があるのではないでしょうか?

4

9 に答える 9

6

いいえ、それは良い考えではありません。List何らかの理由で からの特定の動作が必要でない限り、リスト変数を宣言するために常に interface() を使用する必要がありますArrayList
また、そうする場合は、返されるリストがArrayList. この場合、 の約束された契約はgetObjs()、戻り値の型がある種の であるということだけなListので、それ以外は想定しないでください。List返される now がであっても、 の実装者が後で返されるの型を変更することをArrayList妨げるものは何もありません。これにより、コードが壊れます。getObjs()List

于 2012-08-08T14:53:27.677 に答える
4

呼び出している API によって定義された戻り値の型にキャストします。

を返すと言う場合List<SomeObj>、それはそうです。次の理由により、基になる型を取得しようとしないでください。

a)新しいバージョンで(または呼び出し間でさえ)異なる場合があります

b) 実装クラスを知る必要はありません。

ArrayListが必要な場合は、new ArrayList<SomeObject)(getObjs());

于 2012-08-08T14:55:10.127 に答える
3

インターフェイス (List) を使用するポイントは、実装の詳細を隠すことです。なぜ特定の実装にキャストしたいのですか?

于 2012-08-08T14:54:04.263 に答える
2

あなたは正しいです。それは良い考えではありません。返されるインターフェイス フォームを使用する必要があります。

于 2012-08-08T14:53:38.303 に答える
1

メソッドがどの実装を返すかわからないため、これはお勧めできません。でない場合はArrayList、を取得しClassCastExceptionます。実際、メソッドが返す正確な実装について心配する必要はありません。List代わりにインターフェースを使用してください。

何らかの理由で絶対にが必要な場合はArrayList、独自のを作成し、メソッドによって返されたArrayListもので初期化します。List

ArrayList<SomeObj> myOwnList = new ArrayList(getObjs());

ただし、非効率的であるため、絶対に必要な場合を除いて、これを行わないでください。ArrayList

于 2012-08-08T14:58:17.270 に答える
1

の代わりに常にインターフェースを使用する必要がありますHandle。これが言語の要点であり、OOP後で実装を切り替えることができます。

Cast具象クラスにキャストしている場合、コンパイラは、発生する可能性のある例外の可能性について警告します。SuppressWarningタイプがよくわかれば使用できます。

于 2012-08-08T14:57:10.983 に答える
1

それが a を返す理由は、そのListインターフェースの根底にあるものを気にする必要がないようにするためです。

Listインターフェイスは、オブジェクトが満たす必要のあるコントラクトと、それをクエリする方法を宣言するだけです。ライブラリの作成者は、将来、ArrayList、a LinkedList、またはおそらく aを自由に選択できLazyDatabasePopulatedListます。実際、提供するクラスがどのように実装されているかによって、実行時に異なる実装が得られる場合があります。

従うべき契約がある限り、これはあなたに多くの自由をもたらします. 対話とインターフェイスの提供のみを行い、具体的なクラスをできるだけ扱わないようにすることについては、多くのことが言えます。

于 2012-08-08T14:56:11.393 に答える
1

なぜあなたはこれをしないのですか:

List<SomeObj> objs = getObjs();

そして、そのリストを操作します。何らかの理由でArrayListが本当に必要な場合は、いつでも実行できます

ArrayList<SomeObj> arrayList = new ArrayList<SomeObj>();
arrayList.addAll(objs);

そして、それで作業してください。ただし、これはあまり効率的ではありません。

于 2012-08-08T14:59:41.857 に答える
1

実際には LinkedList であるときに ArrayList にダウンキャストすると、ClassCastException がスローされます。一般に、特にダウンキャストするオブジェクトを返すコードを記述していない場合は、このようにダウンキャストすることは決して良い考えではありません。さらに、このようなサードパーティのライブラリを使用している場合、コードが改善されると、返されるものが変わる可能性があります。このようなダウンキャストをコードに入れると、今日はうまくいくかもしれませんが、ライブラリをアップグレードすると突然壊れます。また、コンパイル時ではなく実行時に壊れるため、実行するまで壊れていることはわかりません。これは、ライブラリが List インターフェイスのみを使用するという契約に違反しているという問題です。

于 2012-08-08T14:54:33.873 に答える