如何在Sets.powerSet中使用通配符泛型

时间:2015-01-12 14:05:52

标签: java generics guava

我有一些像这样的代码

import com.google.common.collect.Sets;
public void handleInput(Set<Object> conditions){
    Set<Set<Object>> powerSet = Sets.powerSet(conditions);
    ...
}

这很好用。但我想这样做:

public void handleInput(Set<? extends Object> conditions){
    Set<Set<? extends Object>> powerSet = Sets.powerSet(conditions);
    ...
}

所以我可以得到作为对象子类的对象的powerset。但这不会编译,我得到错误:

Type mismatch: cannot convert from Set<Set<capture#1-of 
? extends Object>> to Set<Set<? extends Object>>

我如何实现这一目标?

编辑:我想这与在编译时被删除的泛型类型有关,因此编译器无法知道powerSet不会添加非法的东西到它的集合中创建。我通过将所有输入转换为Object并完全删除通配符来重新设计客户端。这是最好的方法吗?谢谢!

2 个答案:

答案 0 :(得分:3)

在这种情况下它没有任何意义 - 因为所有Java类在某些时候扩展java.lang.Object。 所以? extends Object是多余的。

但是谈到Sets.powerSet,这就像一个魅力:

public class TestClass {

    public static class A {}

    public static class B extends A {}

    public static class C extends B {}


    public Set<? extends Set<? extends A>> exampleMethod(Set<? extends A> input) {
        return Sets.powerSet(input);
    }

    public static void main(String[] args) {
        final TestClass testClass = new TestClass();
        final A a = new A();
        final B b = new B();
        final C c = new C();

        System.out.println(
            testClass.exampleMethod(
                    ImmutableSet.of(a, b, c)
            )
        );
    }

}

答案 1 :(得分:1)

正如@slnowak所说,当你扩展Object时,代码实际上是多余的。

然而,要理解异常并避免它......

public void handleInput(Set<? extends Object> conditions){
    Set<? extends Set<? extends Object>> powerSet = Sets.powerSet(conditions);
    ...
}

这将编译,更有用的是,您可以使用此方法限制条件参数中的类型 - 例如 - 您可以:

public void handleInput(Set<? extends Number> conditions){
    Set<? extends Set<? extends Number>> powerSet = Sets.powerSet(conditions);
    ...
}

这会阻止您传入具有非数字类型的集合,并在编译时向您发出警告。