Java 在ArrayList中添加对象(通过使用BeanUtils进行防御性复制)以提供过时数据:Spring 3
客户道等级:Java 在ArrayList中添加对象(通过使用BeanUtils进行防御性复制)以提供过时数据:Spring 3,java,list,spring-3,defensive-copy,Java,List,Spring 3,Defensive Copy,客户道等级: public class CustomerDTO { private int customerId; private String customerName; private String customerAddress; public int getCustomerId() { return customerId; } public void setCustomerId(int customerId) {
public class CustomerDTO {
private int customerId;
private String customerName;
private String customerAddress;
public int getCustomerId() {
return customerId;
}
public void setCustomerId(int customerId) {
this.customerId = customerId;
}
public String getCustomerName() {
return customerName;
}
public void setCustomerName(String customerName) {
this.customerName = customerName;
}
public String getCustomerAddress() {
return customerAddress;
}
public void setCustomerAddress(String customerAddress) {
this.customerAddress = customerAddress;
}
}
具有复制的对象:BeanUtils.copyProperties(targetCustomer、origCustomer)代码>//春天的小海狸
getCustomerList with customerIds =[1,2,3,4]
correct output: 1
correct output: 2
correct output: 3
correct output: 4
wrong output: 4
wrong output: 4
wrong output: 4
wrong output: 4
无复制对象:BeanUtils.copyProperties(targetCustomer、origCustomer)代码>//春天的小海狸
getCustomerList with customerIds =[1,2,3,4]
correct output: 1
correct output: 2
correct output: 3
correct output: 4
wrong output: 4
wrong output: 4
wrong output: 4
wrong output: 4
有人能解释一下这种行为的错误或可能的解释吗?
更新:使用小海狸的目的:
在从方法getCustomer()
返回CustomerDTO对象之前,我试图使用可变对象的防御副本。所以我尝试使用浅层克隆
更新:删除了不变性这个词,因为它使用错误。您使用了错误的工具
您的问题是您将SpringBean与JavaBean混为一谈
Springbean是单例的,因此在Spring上下文中只有一个CustomerDTO
。Spring上下文并不能替代真正的DAO
在DAO中使用映射
或数据库,不要尝试使用Spring上下文进行数据存储和检索操作
correct output: 1
correct output: 2
correct output: 3
correct output: 4
wrong output: 1
wrong output: 2
wrong output: 3
wrong output: 4
如果列表包含相同的对象,则可能会发生这种情况,那么为什么列表包含相同的对象,以及下面的操作如何进行
wrong output: 4
wrong output: 4
wrong output: 4
wrong output: 4
origCustomer包含的引用是CustomerDTO@60bc92,它是由spring维护的单例,因此它始终具有相同的引用。targetCustomer的参考将更改。但是BeanUtils.copyProperties(targetCustomer、origCustomer);将targetCustomer的属性复制到origCustomer meansCustomerDTO@60bc92.
correct output: 1
correct output: 2
correct output: 3
correct output: 4
现在为什么要从Spring上下文创建origCustomer,比如
for(Integer id:customerIds){
CustomerDTO customer = getCustomer(id);
System.out.println("correct output: "+customer.getCustomerId());//getting correct output here
customerList.add(customer);//Trying to add copied object in list
}
for(customer ids 1 to 4){
customer will get reference CustomerDTO@60bc92 and will be updated based on customer ids
so it is printing correct values
but it is adding same reference CustomerDTO@60bc92 to the list
}
for(CustomerDTO customer: customerList){
System.out.println("wrong output: "+customer.getCustomerId());//getting wrong output here
}
for(all customer object in list which is same object reference and having latest value means 4){
it is printing wrong value as 4
}
因为来自spring的BeanUtils需要默认初始化的Springbean
此问题的解决方案:
CustomerDTO origCustomer = _springContext.getBean(CustomerDTO.class);
使用org.apache.commons.BeanUtils.BeanUtils中的BeanUtils代码>在传递给BeanUtils之前,您将有兴趣了解如何初始化您的targetCustomer。我假设您是从getCustomer(int)方法返回targetCustomer。通过任何更改,您每次都返回目标客户的“相同”实例。不可变对象在哪里?我没有看到任何最终变量。@可选:我正在从数据库中提取数据以初始化targetCustomer,然后再传递给Bean Utils。@tom:据我所知,这仍然很小,我无法使用spring将CustomerDTO类设为最终类,我只能将几个CustomerDAO方法设为最终类。如果您能在Spring中引用/告诉我这样做的方法,我将不胜感激。Downvoter:请分享您的评论或回答问题。您能否解释一下测试用例:“使用不可变对象”?使用BeanUtils的目的:我试图在从方法getCustomer()返回CustomerTo对象之前使用可变对象的防御副本。因此,我尝试在以下帖子中使用浅层克隆:。如果您能告诉我正确的工具,我将不胜感激。@ritesh为什么您认为您有不可变的对象?我看不出你的设计有任何不变性。@ritesh发现了我的错误并更正了我的答案BeanUtils.copyProperties()
适用于此用例。但是您仍然试图将Spring上下文用于任何它不是为之设计的东西。我非常感谢您回答这个问题。我认为不可变对象正在制造一些混乱。我的意图是让这个方法CustomerDTO-getCustomer(int-customerId)
返回一个不可变的对象,这个对象将是CustomerDTO,我正试图使用BeanUtils来实现它,然后我将这些对象添加到方法list-getCustomerList(list-customerId)
中的列表中。希望这能增加一些清晰度