Java: T obj; тип obj.getClass () - это Class , а не Class . почему?

В такой функции:

 void foo(T obj)

Тип obj.getClass () - Class > , а не Class расширяет T> . Почему?

Следующий код работает нормально:

String foo = "";
Class fooClass = foo.getClass();

Итак, подпись T # getClass () , похоже, возвращает Class расширяет T> , верно?

Почему сигнатура отличается, если T действительно является универсальным?

Чтобы решить проблему (и чтобы было более понятно, о чем я брожу), Я реализовал эту функцию:

@SuppressWarnings("unchecked") static  Class classOf(T obj) {
    return (Class) 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 classOf(T[] array) {
    return (Class) array.getClass().getComponentType();
}

Это снова безопасно для использования?


Чтобы уточнить, о чем я думаю. Рассмотрим этот демонстрационный код:

static interface I {
    Class myClass();
}

static class A implements I {
    public Class myClass() {
        return this.getClass();
    }
}

static  void foo(I obj) {
    Class clazz = obj.myClass(); // this works
}

Это отлично работает. Но то же самое не относится к Object # getClass () .

Почему, например, было невозможно иметь общий интерфейс, такой как ClassInstance с функцией ] getClass () и каждый объект Java автоматически реализует это? Это будет иметь именно те улучшения, о которых я говорю, по сравнению с решением, позволяющим расширить его от неуниверсального базового класса , объекта .

или наличия объекта в качестве универсального класса:

static abstract class Object {
    abstract Class myClass();
}

static class B extends Object {
    public Class myClass() {
        return this.getClass();
    }
}

static  void bar(Object obj) {
    Class clazz = obj.myClass(); // this works
}

Теперь подумайте о myClass () как о getClass () и подумайте о том, что компилятор автоматически добавит это к каждому классу. Это решило бы многие проблемы с кастингом.

Главный вопрос, о котором я говорю, это: почему не было?


Или, говоря другими словами: Здесь я более подробно опишу решение такой функции classOf , которая решает проблему. Почему это не было сделано таким образом, то есть почему исходная функция не такая?

(Я действительно не хочу получать ответ вроде: как сейчас работает Java, то есть расширение от необщего Объект , который определяет эту функцию, делает это невозможным. Я спрашиваю, почему это не было решено как-то иначе, чтобы это было возможно.)

9
задан Community 23 May 2017 в 12:31
поделиться