Рефлексия

Для того, чтобы использовать рефлексию кроссплатформенный образом, libGDX предоставляет небольшую обертку вокруг API рефлексии Java. Данная обертка в основном состоит из двух классов, содержащих статические методы, которые вы будете вызывать для операций рефлекции:

  • ArrayReflection – инкапсулирует доступ к java.lang.reflect.Array.
  • ClassReflection – инкапсулирует доступ к java.lang.Class.

Другие классы, включенные в обертку, предоставляют доступ к конструкторам, методам и полям. Данные классы (по большей части) отражают их java.lang.reflect эквивалент и могут быть использованы таким же образом.

Использование

В основном вы будете использовать обертку рефлексии таким образом, как вы бы использовали API рефлексии Java, за исключением того, что все вызовы идут через соответствующие классы обертки, вместо прямого вызова метода.

Примеры:

  1. Создает новый экземпляр массива заданного типа.
    Java Обертка
    Array.newInstance(clazz, size) ArrayReflection.newInstance(clazz, size)
  2. Возвращает Class объект для указанного имени класса.
    Java Обертка
    Class.forName("java.lang.Object") ClassReflection.forName("java.lang.Object")
  3. Создает новый экземпляр класса.
    Java Обертка
    clazz.newInstance() ClassReflection.newInstance(clazz)
  4. Возвращает поля класса
    Java Обертка
    clazz.getFields() ClassReflection.getFields(clazz)

GWT

Так как GWT не позволяет использовать рефлексию таким же путем как Java, необходимы дополнительные шаги чтобы сделать информацию о рефлексии доступной в GWT приложении. Вкратце вы должны указать, какие классы вы планируете использовать вместе с рефлексией. Когда компилируется HTML проект, libGDX берет данную информацию и генерирует кэш рефлексии, содержащий информацию и предоставляющий доступ к конструкторам, полям и методам указанных классов. Затем libGDX использует данный кэш рефлексии для реализации API.

Классы указываются посредством включения специального конфигурационного свойства в определение GWT модуля (*.gwt.xm).

Чтобы включить один класс:

<extend-configuration-property name="gdx.reflect.include" value="com.me.reflected" />

Чтобы включить весь пакет:

<extend-configuration-property name="gdx.reflect.include" value="com.me.reflected.ReflectedClass" />

Вы также можете исключить классы из пакетов, например, когда нужно включить пакет, но вы не хотите включать все классы или субпакеты:

<extend-configuration-property name="gdx.reflect.exclude" value="com.me.reflected.NotReflectedClass" />

Примечание

  • Вы должны указать полное имя класса или пакета.
  • Вы должны указать каждый класс или пакет в его собственном extend-configuration-property элементе.
  • Любые классы, ссылающиеся на данные классы, включенные вами, будут автоматически включены, поэтому вам нужно включать только ваши собственные файлы.
  • Вложенные классы не могут быть включены напрямую. Например, если хотите, чтобы для CustomActor$CustomActorStyle класса был доступна рефлексия (возможно, для использования в uiskin.json), просто включите родительский класс (CustomActor в данном примере).
  • Ограничения видимости могут привести к тому, что компилятор не включит ваш класс в IReflectionCache. Поэтому рекомендуется public видимость.