Как Spring может получить информацию об общем типе во время выполнения в отношении строго типизированной коллекции?

Я прочитал ниже в документе Spring 3.0:

Строгая типизированная коллекция (только Java 5+)

В Java 5 и более поздних версиях можно использовать строго типизированные коллекции (используя универсальные типы). То есть можно объявить тип Collection так, чтобы он мог содержать только элементы String (например). Если вы используете Spring для внедрения зависимостей строго типизированной коллекции в bean-компонент, вы можете воспользоваться поддержкой преобразования типов Spring, чтобы элементы ваших экземпляров строго типизированной коллекции были преобразованы в соответствующий тип перед добавлением в Коллекция.

public class Foo {

  private Map<String, Float> accounts;

  public void setAccounts(Map<String, Float> accounts) {
      this.accounts = accounts;
  }
}

<beans>
  <bean id="foo" class="x.y.Foo">
      <property name="accounts">
          <map>
              <entry key="one" value="9.99"/>
              <entry key="two" value="2.75"/>
              <entry key="six" value="3.99"/>
          </map>
      </property>
  </bean>
</beans>

Когда свойство account объекта foo bean подготовлено для внедрения, общая информация о типе элемента строго типизированной карты доступна путем отражения. Таким образом, инфраструктура преобразования типов Spring распознает различные значения элементы типа Float, а строковые значения 9,99, 2,75 и 3,99 преобразуются в действительный тип Float.

Как это может быть возможным? Насколько я знаю, информация об универсальном типе стирается во время компиляции.


person zx_wing    schedule 10.03.2012    source источник


Ответы (1)


Это работает, потому что типы стираются для объектов, но не для полей. Взгляните на Где общие типы хранятся в файлах классов Java? для подробного объяснения того, как это работает.

По сути, существует Field.getGenericType(), представленный в (сюрприз) 1.5, который всегда возвращает надежный универсальный тип поля. Итак, Spring способен считывать accounts универсальных типов (<String, Float>) посредством простого отражения.

Обратите внимание, что используется тот же механизм, например. в jpa. Это полностью допустимо и работает:

@Entity
public class Customer {

    @OneToMany
    private Set<Order> orders;

}

@Entity
public class Order {

    @Id
    private Integer id;

}

Без этой функции Java 5 провайдер JPA не смог бы выяснить, что является второй стороной отношения orders один-ко-многим.

person Tomasz Nurkiewicz    schedule 10.03.2012