Ответ 1
O не является общим типом - это просто простой объект.
Это не проблема. Проблема... и первопричина обеих ошибок компиляции... заключается в том, что D
является общим классом. И это общее, потому что это нестатический вложенный класс в родовом классе. Его полное имя будет some.pkg.C<T>.D
.
FYI: реальный D использует общий параметр T.
И тот факт, что он может использовать T
, является тем, что делает D
общий класс.
Причина, по которой вы не можете использовать instanceof D
или (D)
, является стиранием общего типа. В принципе, среда выполнения не может различать типы (скажем) C<String>.D
и C<Integer>.D
. И поскольку он не может этого сделать, он не может определить, должен ли instanceof D
возвращать true
или false
, или если (D)
должен преуспеть или выбросить ClassCastException
.
Одним из решений было бы объявить D
статическим. Но это не будет работать с вашим "реальным D", потому что статический класс не может использовать параметр универсального типа из окружающего класса (ов). Ваш "FYI" говорит, что он это делает.
Другим решением является создание экземпляра внешнего класса C
, передающего ему фактический тип T
в качестве экземпляра java.lang.Class<T>
. Затем используйте этот экземпляр Class
для реализации проверок типов выполнения и выполнения при необходимости. Это, вероятно, будет грязным.
Третье решение - тщательно проанализировать код и определить, безопасно ли оно для аннотаций @SuppressWarning для подавления предупреждений о "небезопасных отбросах" и т.д.
Какое стирание стилей? 'o' имеет тип Object напрямую.
Фактически Object
является объявленным типом переменной o
. Фактический объект, скорее всего, будет иметь другой тип, и именно этот тип (если это экземпляр D
, например) подвергнется стиранию типа.