Java отражение получает суперкласс получил неожиданный результат - PullRequest
3 голосов
/ 10 октября 2019

При изучении Java-рефлексии у меня возникла некоторая проблема при тестировании getSuperclass()

Ниже приведен мой тестовый код:

System.out.println(java.io.Closeable.class.getSuperclass());

В моем ожидании эта строка должна напечатать что-то вроде AutoClosable потому что это класс, от которого Closable расширяется. Однако это оказывается null. Я попытался объяснить это как Closable находит в java.io, тогда как AutoClosable находит в java.lang и getSuperclass() будет искать только в области действия пакета.

Но это объяснение не имеет смысла, если я напишу так:

Closeable closeable = () -> {

    };
System.out.println(closeable.getClass().getSuperclass());

Приведенный выше код приводит к class java.lang.Object. Результат делает эту проблему более специфической и трудной для понимания.

Как java реализует этот метод getSuperclass() и почему этот метод не возвращает результат, соответствующий его имени?

Ответы [ 3 ]

6 голосов
/ 10 октября 2019

Ни Closeable, ни AutoCloseable не являются классами, они оба являются интерфейсами.

getSuperclass возвращает только суперклассы, но не суперинтерфейсы. Если метод вызывается для чего-то, что не является классом (например, интерфейс или тип примитива), метод возвращает null.

. Возможно, вы захотите вызвать getInterfaces.

4 голосов
/ 10 октября 2019

Closeable - это интерфейс, он не имеет суперкласса, только суперинтерфейсы.

Как говорится в документации getSuperclass():

Если этот класс представляет либо класс Object, интерфейс, тип примитива или void, то возвращается значение null.

Closeable closeable = () -> {

};

эффективно создает конкретный класс, который реализует Closeable: Closeableимеет единственный абстрактный метод close(), который вы реализуете с пустым телом. По сути, это то же самое, что и запись:

Closeable closeable = new Closeable() {
  @Override public void close() {}
}

Этот класс имеет суперкласс, поскольку все классы, кроме Object, имеют суперкласс. Этот суперкласс Object, в спецификацию :

Если Identifier в ClassOrInterfaceTypeToInstantiate обозначает интерфейс, I, то анонимный прямой подкласс Object, который реализует I, объявлен.

3 голосов
/ 10 октября 2019

Этот метод getSuperClass говорит:

Возвращает класс, представляющий суперкласс сущности (класс, интерфейс, тип примитива или void), представленный этим классом.

В вашем случае супер класс - это Object. Потому что вы смотрите на экземпляр класса.

Значение: во втором примере вы создали лямбду, в основном: анонимный внутренний класс .

Чтобы собрать информацию о реализованных (или расширенных) интерфейсах, используйте getInterfaces .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...