Да, члены параметризованного типа JLS3 # 4.5.2 могут закончиться конфликтами, которые исключаются в обычном объявлении класса (# 8.4.8). Довольно много примеров такого рода.
А в Java ни один конструктор в вашем примере не является более конкретным, чем другой, потому что между T
и Integer
нет отношения подтипов. см. также Ссылка на дженерики неоднозначна
Если перегрузка метода создает такую двусмысленность, мы обычно можем использовать разные имена методов. Но конструкторы не могут быть переименованы.
Больше софистики:
Если <T extends Integer>
, то действительно T
является подтипом Integer
, тогда 2-й конструктор более специфичен, чем 1-й, и будет выбран 2-й.
На самом деле javac не позволил бы этим двум конструкторам сосуществовать. В текущей спецификации языка Java нет ничего, что запрещало бы их, но ограничение в байт-коде заставляет javac запрещать их. см. Стирание и перегрузка типов в Java: почему это работает?
Еще один момент: если <T extends Integer>
, поскольку Integer
равно final
, T может быть только Integer
, поэтому Integer
также должен быть подтипом T
, поэтому не является вторым конструктором конкретнее 1-го?
Нет. final
не учитывается в отношениях подтипов. Фактически можно удалить final
с Integer
за один день, и Java даже указывает, что удаление final
не нарушает бинарную совместимость.