15

実行時にスキーマが認識される一般的なテーブル ローダーを開発しようとしています。getInt(int index)これには、さまざまなタイプの要素のリストを含み、 、asString(int index)、などのさまざまな get および set メソッドをサポートするクラスが必要asStringList(int index)です。私が検討する要素のIntegerタイプDoubleは、、、、、StringおよびList<Integer>です。各要素の実際の型は実行時に認識されるので、さらに処理するためにスキーマを記述した List に格納します。List<Double>List<String>

私の質問は: そのような要素のリストを or に保存する必要がありList<Object>ますList<? extends Object>か? または、そのようなクラスを実装するより良い方法はありますか?

4

2 に答える 2

20

あなたのクラスの共通の祖先はObjectであり、List<? extends Object>物事をよりきれいにするわけではないため (結局のところ、すべてが extendsであるため)、それはOK の選択のObjectように見えます。List<Object>

ただし、そのようなリストは混合バッグになります。内部のオブジェクトの実行時のタイプを確認し、それに基づいて決定を下す必要があります。これは間違いなく良いことではありません。

より良い代替手段は、リストの要素に対する操作を統一された方法で実装する独自のクラスを作成し、これらの操作を異なる方法で実装するサブタイプごとに 1 つのサブクラスを作成することです。これにより、リストを統一された方法で処理し、オブジェクトごとの差別化をラッパーにプッシュできます。

public interface ItemWrapper {
    int calculateSomething();
}

public abstract class IntWrapper implements ItemWrapper {
    private int value;

    public IntWrapper(int v) {
      value=v; 
    }

    public int calculateSomething() {
      return value;
    }
}

public abstract class DoubleListWrapper implements ItemWrapper {
    private List<Double> list;

    public DoubleListWrapper (List<Double> lst) {
      list = lst; 
    }

    public int calculateSomething() {
        int res;
        for (Double d : list) {
            res += d;
        }

        return res;
    }
}
// ...and so on

ItemWrapperオブジェクトのリストを作成し、calculateSomethingそれらのタイプをチェックせずに作成できるようになりました:

List<ItemWrapper> myList = new ArrayList<ItemWrapper>();

for (ItemWrapper w : myList) {
    System.out.println(
      w.calculateSomething());
}
于 2013-06-14T21:40:39.503 に答える
9

List<Object>、または最も近いスーパークラスを使用する必要があります。以前、同様の質問をしたことがありますが、その回答には多くの関連情報が含まれている非常に優れた回答がいくつかありました。私はそれをチェックアウトします。基本的に、すべてはPECS に帰着します - Producer Extends, Consumer Super .

于 2013-06-14T21:38:37.713 に答える