Что означает разрешение типа в Java?

Что означает разрешение типа в Java?

Вот несколько примеров использования с моими попытками понять их:

Из Field#getGenericType():

Если тип базового поля является переменной типа или параметризованным типом, он создается. В противном случае он разрешен.

  • Необходимо создать переменные типа или параметризованные типы, чтобы эта форма отражения работала, потому что они не могут быть загружены, потому что они на самом деле не существуют во время выполнения?
  • Итак, если что-то существует во время выполнения, оно может быть "разрешено"? Под загрузчиком классов?

Из TypeToken#resolveType():

Разрешает данный тип в отношении типа, представленного этим типом. Например:

new TypeToken<List<String>>() {}.resolveType(
    List.class.getMethod("get", int.class).getGenericReturnType())
=> String.class
  • Этого я вообще не понимаю. Не уверен, что делает этот код.

Ответы

Ответ 1

Что касается вашего первого вопроса, рассмотрите объявление поля, например

public List<String> parameterizedField;

JVM не поддерживает объект, представляющий тип List<String> (как и объект Class). Поэтому необходимо создать новый объект Type (ParameterizedType в данном случае), представляющий этот тип и возвращающий его (он также может кэшировать его для будущего использования). Он будет делать то же самое для

public E genericField;

создание объекта TypeVariable в этом случае.

Для

public String regularTypeField;

однако тип известен, JVM поддерживает объект Class для String и поэтому ему нужно только вернуть его.


Во втором случае, тип токена hack

new TypeToken<List<String>>() {}

внутренне создает Type, который представляет List<String>, который в противном случае невозможно было бы получить непосредственно из-за стирания типа.

Вызов resolveType проверяет Type, который вы ему даете, и разрешает его на основе аргумента типа TypeToken.

В вашем примере вызываемый getGenericReturnType() возвращает Type, представляющий переменную типа, объявленную в классе List. Поскольку вы параметризовали List с помощью String, resolveType() вернет String. Он связывает аргумент типа, указанный вами в маркете типа, с его соответствующей переменной типа, используемой в методах или полях.

Если вы использовали

new TypeToken<List<String>>() {}.
    resolveType(Iterator.class.getMethod("next").getGenericReturnType())

он вернул бы E, потому что эта переменная типа не связана с той, которую вы привязали в маркере типа.


Использование разрешенных в обоих случаях разных.