2015-01-12 2 views
0

У меня есть некоторый код, как этотКак использовать подстановочные дженерики с Sets.powerSet

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

Как достичь этой цели?

EDIT: Я думаю, что это связано с тем, что генерический тип стирается во время компиляции, поэтому компилятор не может знать, что powerSet не добавит что-то незаконное к создаваемым наборам. Я переработал клиент, введя все входы в Object и полностью удалив подстановочный знак. Это лучший способ? Благодаря!

+0

Что делает? extends Object 'дает вам? Каждый класс java расширяет Object в какой-то момент. Это избыточно. – slnowak

+0

Это не имеет никакого отношения к стиранию, вам просто нужен 'Set > '. –

ответ

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) 
      ) 
     ); 
    } 

} 
+0

Этот ответ был бы лучше, если бы вы объяснили, почему вы хотите сделать 'Set ' вместо того, чтобы просто 'Set ', потому что оба будут компилироваться просто отлично. –

1

, как @slnowak нот, когда вы расширяете объект, код действительно излишним.

Однако, чтобы понять Exception и избежать ...

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); 
    ... 
} 

, и это предотвратит передачу в наборах, имеющих нечисловые типы, и предупредит об этом во время компиляции.

Смежные вопросы