问题的来源
写项目时,有一个方法需要返回两种类型的对象,所以我将两个空白的对象作为参数传给方法,在方法里修改。修改时,我没有一条条地填上空白对象的属性,而是贪图方便,将一个新对象赋值给空白对象,结果原来的那个空白对象仍旧是空白的。
问题详情
java不同于C++,在参数传递中只有值传递,没有引用传递。在下面的方法声明里,repairOrder是一个RepairOrder对象的引用,student是一个Student对象的引用:
1 | public boolean getDetailOfRepairOrder(int repairOrderId, |
我将一个r和一个s传给上面的函数:
1 | RepairOrder r = new RepairOrder(); |
程序的结果是,r的name属性是test而不是newR test,为什么?
原因正是JAVA的值传递,在函数中的repairOrder只是对象的引用,而不是对象本身。repairOrder.setName(“test”)改变了对象的属性所以在r中的属性被改变,改为test;而repairOrder = newR改变了repair本身,并不涉及对象,所以在r中的属性没变。
问题的解决方法
引入包装器
是解决方案之一
新建一个RepairOrderWrapper:
1 | package com.ilovecl.myproperty.model.wrapper; |
将r放入包装器:
1 | RepairOrderWrapper repairOrderWrapper = new RepairOrderWrapper( |
将包装器作为参数传给方法,对包装器内部的那个repairOrder引用进行修改,repairOrder也就指向了新对象,不再指向r的对象:
1 | public boolean getDetailOfRepairOrder(int repairOrderId, |
这时包装器内部的repairOrder指向的是新对象,而不是原先的r。要调用新对象的属性,我们要用repairOrderWrapper.getRapairOrder().getName()而不是r.getName():
1 | repairOrderDetailString = repairOrderWrapper.getRepairOrder() |
一条条地赋值是解决方案之二
我们不再建新对象,而是逐条地修改原先的对象内容:
1 | repairOrder.setName("name"); |
如此修改,r指向的对象的内容也就被有效地改变了。