2016-02-06 1 views
1

Я потерян в generics (Java). Реальный сценарий предполагает JPA и CriteriaBuilder «sКак правильно отбирать ожидаемые типизированные аргументы?

<Y extends Comparable<? super Y>> Predicate greaterThan(Expression<? extends Y> x, Y y); 

но я упростил тот же случай в следующий класс:

public class GenericsTest { 

    public class Bean<T> { 

    }; 

    public <T extends Comparable<T>> T targetMethod(Bean<T> bean, T object) { 
     return object; 
    } 

    @SuppressWarnings("unchecked") 
    public <T> T castToGeneric(Bean<T> bean, Object object) { 
     return (T) object; 
    } 

    @SuppressWarnings("unchecked") 
    public <T> void understandGenerics(Bean<T> bean, Object object) { 
     Bean<Comparable<T>> beanOfComparable = (Bean<Comparable<T>>) bean; 
     Comparable<T> comparableObject = this.castToGeneric(beanOfComparable, object); 
     this.targetMethod(beanOfComparable, comparableObject); 
    } 

} 

призывание targetMethod(beanOfComparable, comparableObject) в последней строке генерирует

метод targetMethod(Bean<T>, T) по типу GenericsTest не применяется к аргументам (Bean<Comparable<T>>, Comparable<T>)

, и я не понимаю, где эта проблема, так как T в targetMethod должен быть Comparable<T>, то есть тип я даю его.

ответ

2

Ограничение на вашем targetMethod это то, что вызывает его на провал:

public <T extends Comparable<T>> T targetMethod(Bean<T> bean, T object) 

Когда вы передаете в переменных (Bean<Comparable<X>>, Comparable<X>), вы подразумеваете, что общий параметр Т Comparable<X> (я использую X здесь, чтобы отличить общий от targetMethod и generic от understandGenerics).

Ограничение на targetMethod говорит, что когда ваш T равен Comparable<X>, тогда T должен продлить Comparable<Comparable<X>>. Конечно, это не будет удовлетворено.

Я думаю, что вы собираетесь сделать, лучше было бы осуществить следующим образом:

@SuppressWarnings("unchecked") 
public <T extends Comparable<T>> void understandGenerics(Bean<T> bean, Object object) { 
    T comparable = (T) object; 
    targetMethod(bean, comparable); 
} 

Обратите внимание, с дополнительным ограничением, что T должна быть сопоставима, весь процесс намного проще. В общем, он платит, чтобы максимально ограничить неконтролируемый код и вместо этого накладывать ограничения на типы.

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