Общая ковариация в Java обрабатывается на клиенте. у вас нет семантики, чтобы сказать, что стек является ковариантным, и позволить компилятору проверить, что операции, которые вы разрешаете (например, push), действительны в ковариационной модели. (толчка нет).
Особая проблема заключается в том, что вы можете сделать что-то вроде этого:
Number r = new Rational(a,b); // rationals are also numbers
number.push(r);
, что в базовой структуре подразумевает integer.push (r); // несоответствие типов
(Программирование в Scala дает кристально четкое объяснение различий между клиентом и провайдером (со / против) в главе 19. Рекомендуемое чтение, даже если вы не в Scala)