在返回值中删除wildcard参数

时间:2012-09-09 06:22:55

标签: java generics wildcard

我有一些内部使用泛型的代码。到目前为止,一切都很好,直到通过公共API公开功能。问题与以下玩具示例相同:我有一个List包装的项目,其中包含特定的子类型(在此示例中为T extends Number)。当我想要返回此List时,我目前正在返回List<Wrapper<? extends Number>>,这会使客户端代码非常详细。

是否有可能将返回类型更改为List<Wrapper<Number>>?客户端不需要知道Wrappers包含任何特定类型的Number。我尝试了几种使用转换的方法,但它们都因编译错误而失败。

public static List<Wrapper<? extends Number>> getNumbers() {
    Wrapper<Integer> number1 = new Wrapper<Integer>(1);
    Wrapper<Double> number2 = new Wrapper<Double>(2.);

    List<Wrapper<? extends Number>> numbers = new ArrayList<Wrapper<? extends Number>>();
    numbers.add(number1);
    numbers.add(number2);
    return numbers;
}

class Wrapper<T extends Number> {
    private final T item;
    Wrapper(T item) {
        this.item = item;
    }
    T getItem() {
        return item;
    }
}

3 个答案:

答案 0 :(得分:2)

根据您对Wrapper类型所显示的内容,Wrapper<? extends Number> 完全您想要的案例,因为它只能从您的案例中获取项目Wrapper(它是制作人),并且无法放入项目。因此,当您在getItem()上致电Wrapper<? extends Number>时,会返回Number,这就是您想。它如何不符合您的需求?

“详细”并不是不丢弃类型安全的正当理由。

答案 1 :(得分:0)

据我所知,如果你想要返回T是不可能的。当你想要返回T时,你不能返回T的子类型

答案 2 :(得分:0)

我刚刚发现以下方法有效。任何有关潜在陷阱的反馈和评论仍然非常赞赏。

public static List<Wrapper<Number>> getNumbers() {
    Wrapper<Integer> number1 = new Wrapper<Integer>(1);
    Wrapper<Double> number2 = new Wrapper<Double>(2.);
    List<Wrapper<? extends Number>> numbers = new ArrayList<Wrapper<? extends Number>>();
    numbers.add(number1);
    numbers.add(number2);
    return (List<Wrapper<Number>>)(List<?>)numbers;
}