Как ограничить upcasting типа-параметра?



Задача: запретить этому методу принимать параметры разных типов:

<T> void pair(T a, T b) {}



То есть, нужно разрешить вызывать pair(Foo, Foo), но запретить pair(Foo, Bar).



Upcasting – приведение к типу-родителю. String → Object, Integer → Number.



Дело в том, что у любых двух классов есть общий предок: как минимум Object. Если вызвать этот метод с параметрами String и Boolean – согласно правилам вычисления типа-границы, параметр T будет стерт в Object.



Использовать super тоже не поможет: для этого нужно знать заранее, какой именно тип будет передаваться.



Фокус в том, что на этапе компиляции это невозможно. Объект любого типа всегда является объектом типа-родителя (отношение is a). Это фундаментальное правило ООП, которое невозможно нарушить. К тому же, подобный метод нарушал бы принцип подстановки Лисков.



Единственная возможность добиться желаемого поведения – с помощью getClass() сравнивать классы объектов в рантайме.



#Дженерики



@javatg