15

我正在尝试开发一个通用的表加载器,它的模式在运行时是已知的。这需要一个包含不同类型元素列表并支持各种 get 和 set 方法的类,例如getInt(int index), asString(int index), asStringList(int index)。我考虑的元素类型是Integer, Double, String, and List<Integer>, List<Double>and List<String>。每个元素的实际类型在运行时是已知的,我会将它们存储在一个描述其架构的列表中以供进一步处理。

我的问题是:我应该将这样的元素列表存储在List<Object>or中List<? extends Object>吗?还是有更好的方法来实现这样的类?

4

2 回答 2

20

由于您的类的共同祖先是Object,并且因为List<? extends Object>不会使事情变得更干净(毕竟,一切都 extends Object),所以看起来List<Object>是一个不错的选择。

但是,这样的列表将是一个混合包:您需要检查内部对象的运行时类型,并根据它做出决定。这绝对不是什么好事。

更好的选择是创建自己的类,以统一的方式实现对列表元素的操作,并为每个子类型创建一个子类,以不同的方式实现这些操作。这将使您以统一的方式处理列表,将每个对象的差异推送到您的包装器中。

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 回答