Скажем, у вас есть SubTestClass extends TestClass
, и вы пишете:
TestClass instance = new TestClass();
SubTestClass result = instance.test();
Это законно в отношении подписи вашего test()
класса, хотя это чепуха (1).Компилятор выведет, что T
- это класс SubTestClass
.И тогда становится ясно, что экземпляр TestClass
не instanceof SubTestClass
.Таким образом, при легальном использовании вашего метода test()
возвращение this
может привести к несовпадению типов, и это то, что говорит вам компилятор.
С вашей подписью test()
невозможно вернуть что-либо, кроме null
, потому что null
- единственное значение, которое вы можете присвоить переменной неизвестного типа.
Позвольте мне объяснить последнее утверждение (запрошено в комментариях): реализация метода test()
должна возвращать некоторое значение, которое соответствует типу T
, и конкретный тип (выведенный из ситуации вызовазначение SubTestClass
) не выводится для метода - в аргументах или в полях экземпляра нет ничего, что могло бы считывать требование вернуть SubTestClass
в этой ситуации.В другой ситуации вызова может потребоваться вернуть AnotherSubTestClass
, и он никак не может отличить первое от второй ситуации.
Если вы вернете this
(с использованием приведения (T)
, чтобы сделать егопередать компилятор), он потерпит неудачу ни в первом, ни во втором, ни в обеих ситуациях.Таким образом, вы не можете сделать это без высокого риска сбоя.
Единственное значение, которое вы можете успешно назначить для переменных SubTestClass
и AnotherSubTestClass
, это значение null
.Так что это единственное значение, которое вы можете безопасно вернуть из метода с такой сигнатурой.
(1) Наличие универсального метода, в котором универсальный тип не может быть выведен из параметров, а только из ожидаемого результата.типа, вряд ли может работать - как метод должен знать, что ожидает вызывающая сторона?