java - Spring 如何在运行时获取有关 "Strongly-typed collection"的通用类型信息?

标签 java spring generics type-erasure

我在 Spring 3.0 文档中阅读了以下内容:

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

在 Java 5 及更高版本中,您可以使用强类型集合(使用泛型类型)。也就是说,可以声明一个 Collection 类型,使其只能包含 String 元素(例如)。如果您使用 Spring 将强类型 Collection 依赖注入(inject)到 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>

当 foo bean 的 account 属性准备好注入(inject)时,有关强类型 Map 的元素类型的泛型信息可通过反射获得。 因此 Spring 的类型转换基础结构可以识别各个值元素为 Float 类型,字符串值 9.99、2.75 和 3.99 被转换为实际的 Float 类型。

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

最佳答案

这是有效的,因为对象的类型被删除,但字段的类型没有被删除。看看Where are generic types stored in java class files?了解其工作原理的详细说明。

本质上,有一个 Field.getGenericType() (惊喜)1.5 中引入的方法始终返回字段的可靠泛型类型。所以 Spring 能够读取 accounts通过普通反射的泛型类型 ( <String, Float> )。

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

@Entity
public class Customer {

    @OneToMany
    private Set<Order> orders;

}

@Entity
public class Order {

    @Id
    private Integer id;

}

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

关于java - Spring 如何在运行时获取有关 "Strongly-typed collection"的通用类型信息?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9650723/

相关文章:

java - org.hibernate.MappingException : Unknown entity: java. lang.Integer

Java 泛型 : Example if types are not erased at compilation

使用生成器或类似的 Java 模板类?

java - 如何以正确的方式制作高负载Java应用程序?

java - 无法将 TextField 添加到 Java 中的界面

java - Thymeleaf 迭代对象列表

spring - 从托管在 GitHub 上的 Spring Cloud Config Server 访问的 repo 的身份验证问题

java - 在 Eclipse RAP 中如何将当前 UI 状态推送/强制到客户端?

java - 如何在jsf中使用 session 过滤器作为登录表单

swift - self 类型作为闭包中的参数