5

次のようなクラスがあるとします。

public class foo {
    private List<String> fooThings;

    public void doSomething(List<String> things) {
        // Do a bunch of things here
        // Possibly setting fooThings at some point as well
    }
}

List インターフェイスの代わりに ArrayList などの具体的なクラスを宣言で指定することは適切ですか? もしそうなら、いつ?

編集> この質問は、いつ LinkedList を使用するか、いつ ArrayList を使用するかとは関係ありません。これは、他の場所で回答されている別の質問です。問題は、明確にするためにいつ宣言をインターフェイス (List) にする必要があるか、またメソッドが何をするか、またはインスタンス変数をどのように活用するかが重要であるため、ArrayList などの実装をいつ指定する必要があるかです。

4

7 に答える 7

3

通常はList、構造を宣言するためにのみインターフェイスを使用する必要があります。ただし、まれに、特定の実装でのみ使用できる特定のメソッドを使用する必要がある場合やList、リストの型を明示的に宣言する必要がある場合があります。ただし、これは柔軟性を制限するため、慎重に行う必要があります。LinkedListArrayList

于 2013-09-24T21:00:10.573 に答える
1

List-Interface によって許可されていないリストの特定のプロパティを保証したい場合があります。次の例では、Seralizable ではない List を渡す可能性があり、クラスがシリアル化されたときにランタイム エラーが発生する可能性があります。:

public class foo implements Serializable{

private List<String> fooThings;

public void setFooThings(List<String> things) {
   fooThings = things;
}

}

ArrayList は Serializable を実装します。ジェネリック メソッドを使用してリストがシリアライズ可能であることを確認する方法は他にもあります。たとえば、

public <T extends List & Serializable> setFooThings(T things) 
于 2014-04-30T14:17:14.413 に答える
1

これは の例ではありませんが、ArrayList/LinkedListを返すメソッドは次のListように宣言するとよいと思います。

public ImmutableList doSomething();

ImmutableListGuava のImmutableListはどこにありますか。この種の宣言は、返されたリストが変更されることを意図していないことを明確にするため、コメントではなくコードによって伝達されます (または、実行時にリストを変更しようとしたときの例外のみ)。

于 2013-09-24T20:43:48.377 に答える
0

常に変数を次のように宣言する必要があります。

private List<String> fooThings;

これにより、実際に fooThings を使用しているときに、任意のタイプのリスト、LinkedList、ArrayList などを使用できます。

プログラムの一部で LinkedList を使用し、別の部分では ArrayList の方が適しているため、ArrayList に切り替えることができます。開発中は最大限の柔軟性を確保したいと考えています。

別のクラスからのパラメーターを介して fooThings が初期化される場合にも遭遇する可能性があります。これを特定のタイプのリストとして宣言したくないのは、メソッドの呼び出し元をこの特定のタイプのリストを使用するように制限したり、メソッドを使用する前にリストのタイプを正しいタイプに変換したりすると、不要な作業が発生するためです。

于 2013-09-24T20:58:15.510 に答える
0

実装ではなくインターフェースに書くことは常に良いことです。これにより、渡されたインターフェイスを実装するさまざまな具体的な型を柔軟に処理できるようになります。

あなたのサンプルコードはもう1つの抽象的なレベルです

public class foo {
    private Collection<String> fooThings;

    public void doSomething(Collection<String> things) {
        // Do a bunch of things here
        // Possibly setting fooThings at some point as well
    }
}

利点 - これにより、さまざまな具体的なタイプの入力を処理できます。

欠点 - 具体的なタイプの特定の機能を使用する必要が制限されます。たとえば、LinkedList に固有の getFirst() を使用できない場合があります。

インターフェースへのコード - 柔軟な/疎結合のコード。実装へのコード - 特別な操作用。

于 2013-09-24T21:13:47.560 に答える