В такой функции:
void foo(T obj)
Тип obj.getClass ()
- Class >
, а не Class расширяет T>
. Почему?
Следующий код работает нормально:
String foo = "";
Class extends String> fooClass = foo.getClass();
Итак, подпись T # getClass ()
, похоже, возвращает Class расширяет T>
, верно?
Почему сигнатура отличается, если T
действительно является универсальным?
Чтобы решить проблему (и чтобы было более понятно, о чем я брожу), Я реализовал эту функцию:
@SuppressWarnings("unchecked") static Class extends T> classOf(T obj) {
return (Class extends T>) obj.getClass();
}
Снова вопрос: почему приведение нужно здесь, а не в случае String
? И почему
Требуется подавление предупреждений
? Разве из кода не всегда ясно, что он всегда сможет безопасно выполнить это приведение?
Можно ли каким-то образом получить Class расширяет T>
из obj
? Если да, то как? Если нет, то почему?
Один из способов - использовать classOf
. Это было бы безопасно, правда? Если это всегда безопасно и дает надежный способ действительно получить Class extends T>
(вместо Class >
), почему в Java нет такой функции? Или есть?
Как насчет того случая:
void bar(T[] array)
array.getClass (). GetComponentType ()
снова возвращает Class >
, а не Class расширяет T>
. Почему?
Я реализовал эту функцию:
@SuppressWarnings("unchecked") static Class extends T> classOf(T[] array) {
return (Class extends T>) array.getClass().getComponentType();
}
Это снова безопасно для использования?
Чтобы уточнить, о чем я думаю. Рассмотрим этот демонстрационный код:
static interface I {
Class extends T> myClass();
}
static class A implements I {
public Class extends A> myClass() {
return this.getClass();
}
}
static void foo(I obj) {
Class extends T> clazz = obj.myClass(); // this works
}
Это отлично работает. Но то же самое не относится к Object # getClass ()
.
Почему, например, было невозможно иметь общий интерфейс, такой как ClassInstance
с функцией ] getClass ()
и каждый объект Java автоматически реализует это? Это будет иметь именно те улучшения, о которых я говорю, по сравнению с решением, позволяющим расширить его от неуниверсального базового класса , объекта
.
или наличия объекта
в качестве универсального класса:
static abstract class Object {
abstract Class extends T> myClass();
}
static class B extends Object {
public Class extends B> myClass() {
return this.getClass();
}
}
static void bar(Object obj) {
Class extends T> clazz = obj.myClass(); // this works
}
Теперь подумайте о myClass ()
как о getClass ()
и подумайте о том, что компилятор автоматически добавит это к каждому классу. Это решило бы многие проблемы с кастингом.
Главный вопрос, о котором я говорю, это: почему не было?
Или, говоря другими словами: Здесь я более подробно опишу решение такой функции classOf
, которая решает проблему. Почему это не было сделано таким образом, то есть почему исходная функция не такая?
(Я действительно не хочу получать ответ вроде: как сейчас работает Java, то есть расширение от необщего Объект
, который определяет эту функцию, делает это невозможным. Я спрашиваю, почему это не было решено как-то иначе, чтобы это было возможно.)