如果 java 是按值传递的,为啥我的对象在执行方法后会发生变化?
Posted
技术标签:
【中文标题】如果 java 是按值传递的,为啥我的对象在执行方法后会发生变化?【英文标题】:If java is passed-by-value why my object changes after executing the method?如果 java 是按值传递的,为什么我的对象在执行方法后会发生变化? 【发布时间】:2015-08-03 06:32:38 【问题描述】:我正在调试我的方法,它以某种方式更新了我的 element
变量。即使我不在方法中使用该变量。
代码:
private static List<Mapping> createFormFieldsMapping(ArrayList<String> CDOfields,
List<Mapping> fieldMappings, Element element)
System.out.println(" - Creating field mappings for "+element.name);
for (Mapping fieldMapping : fieldMappings)
if (fieldMapping.targetEntityFieldId!=null)
String formField = getContactFieldNameById(fieldMapping.targetEntityFieldId);
formField = formField.trim();
formField = formField.replaceAll("-", "");
formField = formField.replaceAll("_", "");
formField = formField.replaceAll(" ", "");
formField = formField.toLowerCase();
Boolean matchFound = false;
for (String cdoField : CDOfields)
String[] cdoFieldSplit = cdoField.split(";",-1);
String cdoFieldModified =cdoFieldSplit[1].trim();
cdoFieldModified = cdoFieldModified.replaceAll("-", "");
cdoFieldModified = cdoFieldModified.replaceAll("_", "");
cdoFieldModified = cdoFieldModified.replaceAll(" ", "");
cdoFieldModified = cdoFieldModified.toLowerCase();
if (cdoFieldModified.equals(formField))
fieldMapping.targetEntityFieldId = cdoFieldSplit[0];
matchFound = true;
break;
if (!matchFound)
// WRITE NOT MATCHED FORM FIELD TO A FILE
element.processingSteps.targetEntityFieldId
正在更改
这是我调用方法的方式:
List<Mapping> fieldMapping = new ArrayList<Mapping>();
Iterator<ProcessingStep> i = element.processingSteps.iterator();
while (i.hasNext())
ProcessingStep step = i.next();
if (step.type.equals("FormStepCreateUpdateContactFromFormField"))
fieldMapping = step.mappings;
step.execute = "never";
//i.remove();
// Update contact field IDs with CDO field IDs
fieldMapping = createFormFieldsMapping(CDOfields, fieldMapping, element);
我想要的只是复制字段映射,通过该方法处理它,然后返回并将其添加到fieldMappings
列表中。
问题是step.mappings
是element
的一部分,但step.mappings
被放入ArrayList
fieldMapping
。因此,我认为元素永远不应该被任何东西编辑。
【问题讨论】:
你是在重新分配,而不是直接改变。 “我正在调试我的方法,它以某种方式更新了我的元素变量” - 不,它没有。element
变量的值与之前完全相同——它是一个对象的reference。该对象中的数据可能已更改(尚不清楚它在您发布的代码中的位置),但这不是一回事。
这里也有一些很好的答案***.com/q/7893492/2991525
我投票支持重新打开,因为这并不是真正的重复:OP 不是关于 java 是按值调用的;这是关于一个特定问题的!
是fieldMappings == element.processingSteps
的情况吗?也就是说,这两个声明指向same引用?
【参考方案1】:
我相信这是因为更改此代码中的 fieldMapping 也会更改元素,因为两者都是对同一对象的“引用”:
fieldMapping.targetEntityFieldId = cdoFieldSplit[0];
要验证是否是这种情况,请添加条件调试中断(或 if 语句和打印/日志)来检查两个对象实例的相等性。
发生这种情况是因为您在以下代码中将 fieldMapping 设置为等于 element.processingSteps.iterator() 指向的对象。
Iterator<ProcessingStep> i = element.processingSteps.iterator();
while (i.hasNext())
ProcessingStep step = i.next();
if (step.type.equals("FormStepCreateUpdateContactFromFormField"))
fieldMapping = step.mappings;
step.execute = "never";
//i.remove();
// Update contact field IDs with CDO field IDs
fieldMapping = createFormFieldsMapping(CDOfields, fieldMapping, element);
如果您不希望这种行为,那么您需要在初始化 fieldMapping 时“深拷贝”step.mappings 对象。
【讨论】:
我觉得你说得对,我一回家就试试。但是,您如何称呼这种行为?即使我创建了新的 ArrayList fieldMapping 并将 step.mappings 放在那里,它仍然只是对同一个对象的引用? ArrayList 是指针的容器,指针是存储引用的对象。这启用了 java 的按值性质,其中指针按值复制,但指针引用的对象(即指针的值)仍然相同。这使得 Java 自诞生以来的速度大大提高,因为它可以避免复制整个对象(这在 Java 中变得相当大)。以上是关于如果 java 是按值传递的,为啥我的对象在执行方法后会发生变化?的主要内容,如果未能解决你的问题,请参考以下文章