Spring在运行时如何获得关于"强类型集合"的泛型类型信息?

zx_*_*ing 0 java generics spring type-erasure

我在下面的Spring 3.0文档中阅读:

强类型集合(仅限Java 5+)

在Java 5及更高版本中,您可以使用强类型集合(使用泛型类型).也就是说,可以声明Collection类型,使其只能包含String元素(例如).如果您使用Spring依赖注入一个强类型的Collection到bean中,您可以利用Spring的类型转换支持,这样强类型Collection实例的元素在被添加到之前就会转换为适当的类型收藏.

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>
Run Code Online (Sandbox Code Playgroud)

当foo bean的accounts属性准备好进行注入时,可以通过反射获得有关强类型Map的元素类型的泛型信息.因此,Spring的类型转换基础结构将各种值元素识别为Float类型,并将字符串值9.99,2.75和3.99转换为实际的Float类型.

这怎么可能?据我所知,通用类型信息在编译期间被删除.

Tom*_*icz 6

这是有效的,因为类型被删除对象,但不是字段.看看java类文件中存储的泛型类型哪里?详细解释它是如何工作的.

本质上,Field.getGenericType()(惊讶)1.5中引入了一种方法,它始终返回可靠的泛型类型的字段.所以,春天能够读取accounts泛型类型(<String, Float>通过纯反射).

注意,例如在使用相同的机制.这完全有效且有效:

@Entity
public class Customer {

    @OneToMany
    private Set<Order> orders;

}

@Entity
public class Order {

    @Id
    private Integer id;

}
Run Code Online (Sandbox Code Playgroud)

如果没有这个Java 5功能,JPA提供程序将无法弄清楚orders 一对多关系的第二方面是什么.