2015-01-02 4 views
2

Я пытаюсь сделать несколько сильных типизированные API:Метод Обобщение связаны ограничения с классом Дженерик

class PropertyType<T> { ... } 
class SubType1<T> extends PropertyType<T> { ... } 
class SubType2<T> extends PropertyType<T> { ... } 

class PropertyHandler<K extends PropertyType<?>> { 

    // Here, the V generics is not related to the property type, 
    // hence the value is not typed 
    public <V> getValue(K prop) { ... } 

    // In this case, we have correct typing, but T is not bounded to K 
    public <V, T extends PropertyType<V>> getValue(T prop) { ... } 

    // This would be a solution, but it doesn't compile because K is a type variable 
    public <V, T extends K & PropertyType<V>> getValue(T prop) { ... } 
} 

И это, как он будет использоваться:

PropertyHandler<SubType1<?>> ph = new PropertyHandler<>(); 

// I want to allow this 
SubType1<Integer> p1 = new SubType1<>(); 
SubType1<Boolean> p2 = new SubType1<>(); 
Integer v1 = ph.getValue(p1); 
Boolean v2 = ph.getValue(p2); 

// I don't want to allow this 
SubType2<Integer> p3 = new SubType2<>(); 
Boolean v3 = ph.getValue(p3); 

Есть ли способ решить это ? Может быть, это проблема с архитектурой, которую можно обрабатывать по-разному?

+0

Я не уверен, что понял вопрос правильно, но вы не могли бы изменить «класс PropertyHandler > "to" class PropertyHandler > ", а затем использовать" public "? Кажется, вы ищете способ ограничить значение K только тем, что установлено в обработчика свойств. – Erik

+0

Да, это именно так. Однако ваше предложение не работает: «class PropertyHandler >« это не скомпилируется, пока вы также не укажете переменную типа X, которая не является тем, что я хочу ... – ctabin

+0

Почему вы не хотите создавать X переменная типа? – Erik

ответ

1

Образец возврата для getValue() должен быть добавлен к общей подписью PropertyHandler. В противном случае нет способа для PropertyHandler вывести тип возврата getValue() из общего определения PropertyType.

Следовательно, либо назначить как тип возвращаемого значения и тип недвижимости в PropertyHandler родовой подписи, или перевернуть его, указав тип возвращаемого значения в PropertyHandler, и с PropertyHandler обеспечить правильный PropertyType тип параметра, например:

class PropertyType<T, H extends PropertyHandler<T>> { 
    public T getValue() { ... } 
} 
class IntegerType extends PropertyType<Integer, PropertyHandler<Integer>> { ... } 
class BooleanType extends PropertyType<Boolean, PropertyHandler<Boolean>> { ... } 

class PropertyHandler<V> { 
    public <T extends PropertyType<V, PropertyHandler<V>>> V getValue(T prop) { 
     return prop.getValue(); 
    } 
} 

Это, как вы бы использовать:

PropertyHandler<Integer> ph = new PropertyHandler<>(); 
IntegerType p1 = new IntegerType(); 
Integer v1 = ph.getValue(p1); // works fine 
BooleanType p3 = new BooleanType(); 
Boolean v3 = ph.getValue(p3); // compile time error 
+0

Спасибо за предложение. Делая это, это позволило бы ограничить использование PropertyHandler некоторыми данными (то есть Integer), но не такими типами (то есть IntegerType). Я отредактировал свое оригинальное сообщение, чтобы включить некоторые подмножества в подклассы. – ctabin

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