一、问题
在spring实践bean注入ArrayList属性的时候报错:
Property of ‘java.util.ArrayList’ type cannot be injected by ‘List’
二、原因分析
在尝试将 Spring 配置中的 注入到一个 ArrayList 类型的属性时出现了类型不匹配问题。核心问题在于:Spring 的 标签创建的是 java.util.LinkedList,而属性声明为 java.util.ArrayList。虽然两者都实现了 List 接口,但它们是不同的具体实现类。
<property name="al">
<list> <!-- Spring 默认创建的是 LinkedList -->
<value>test</value>
<value>9999</value>
</list>
</property>
在java类中:
private ArrayList al; // ArrayList 类型
三、解决方案
方案1:修改属性类型为 List 接口(推荐)
// 修改前
private ArrayList al;
// 修改后(使用接口类型)
private List al; // 或 List<String> 如果有泛型,记得set方法传参类型也要改
优点:符合面向接口编程原则,兼容 Spring 的 标签(它返回 LinkedList)。
方案 2:在 Spring 配置中显式指定 ArrayList
<property name="al">
<!-- 使用 value-type 指定元素类型 -->
<bean class="java.util.ArrayList">
<constructor-arg>
<list value-type="java.lang.String">
<value>fjd</value>
<value>9999</value>
</list>
</constructor-arg>
</bean>
</property>
方案 3:使用 util 命名空间(需要添加 schema)
在 XML 头部添加 util 命名空间:
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util.xsd"
配置 ArrayList:
<util:list id="myList" value-type="java.lang.String" list-class="java.util.ArrayList">
<value>test</value>
<value>9999</value>
</util:list>
<bean id="bookDao" class="com.fjd.dao.impl.BookDaoImpl">
<property name="al" ref="myList"/>
</bean>
四、总结
类型兼容性:
- list标签 默认创建 LinkedList
- 声明为 ArrayList 会导致类型不匹配
最佳实践:
// 推荐:使用接口类型
private List<String> values;
// 不推荐:使用具体实现类
private ArrayList<String> values; // 可能导致注入问题
泛型考虑:
- 如果列表中混合类型(如字符串和数字),确保属性声明为无泛型或 List<类型>
否则可能引发类型转换异常
- 如果列表中混合类型(如字符串和数字),确保属性声明为无泛型或 List<类型>