通过作为方法参数传递对象的副本

Posted

技术标签:

【中文标题】通过作为方法参数传递对象的副本【英文标题】:Copy of object by passing as method parameter 【发布时间】:2015-02-05 21:03:56 【问题描述】:

我对 Java 在方法参数中的引用/值传递有点困惑。

我在 OuterObject 类中有一个构造函数:

private InnerObject io;
public OuterObject(InnerObject io) 
    this.io = io;


public InnerObject getInnerObject()
    return this.io;

如果我将OuterObject 传递给这样的复制方法:

InnerObject io = new InnerObject();
OuterObject o = new OuterObject(io);    
anotherClass.getCopyOf(o);

在另一个班级:

public static OuterObject getCopyOf(InnerObject o)
    return new OuterObject(o.getInnerObject());

如您所见,我使用InnerObject 作为参数创建了OuterObject。现在我想知道:

我是否从 return 语句中得到两个新对象, 还是只是一个新的OuterObject 副本,但对现有InnerObject 的引用相同?

【问题讨论】:

【参考方案1】:

首先,new Object(o.getInnerObject()) 不会编译,因为Object 没有匹配的构造函数。

假设您用new OuterObject (o.getInnerObject()); 替换它,OuterObject 的新实例将包含o 包含的相同InnerObject 实例,因为OuterObject 的构造函数不会创建@ 的副本987654328@ 实例传递给它。

【讨论】:

@MidgarZolom getter 不会改变我的答案(如果 getter 返回了 this.io 的副本,答案就会改变)。【参考方案2】:

您获得的对象与使用 new 关键字创建的对象一样多。

【讨论】:

【参考方案3】:

如果将对象存储在变量或参数中,则始终存储引用。该对象永远不会被复制。仅复制原始类型,例如 intboolean

如果您想创建对象的副本,您应该使用java.lang.Cloneable 接口和Clone 方法或复制构造函数来研究对象克隆。您选择的只是偏好问题。我通常更喜欢复制构造函数,因为它们更清楚地显示正在发生的事情。至少对我来说。

你的return new Object(o.getInnerObject()); 行也不会编译。但我猜你想在这里写OuterObject 而不是Object

【讨论】:

【参考方案4】:

您的代码在此行中存在编译错误: 返回新对象(o.getInnerObject()); o 是 Object 的一个实例。因此,它不能有 getInnerObject() 之类的方法; 此外,Object 没有像 Object(InnerObject) 这样的构造函数。 所以,改变

public static Object getCopyOf(Object o)
    return new Object(o.getInnerObject());

进入

public static OuterObject getCopyOf(Object o)
    return new OuterObject(((OuterObject)o).getInnerObject());

我们现在可以回答您的问题。 'new' 总是会在堆内存中创建一个新对象,但是两个外层对象具有相同的内层对象引用。

【讨论】:

是的,我有点时间压力,我在这里打字时犯了一些错误,我希望我把它们都改正了,但是我的问题的本质应该很清楚并且已经回答了

以上是关于通过作为方法参数传递对象的副本的主要内容,如果未能解决你的问题,请参考以下文章

java中方法的参数传递机制(值传递还是引用传递)

如何通过类对象作为方法参数的RESTful服务吗

Java中的值传递和引用传递

Java中的参数传递

对象作为参数传递给另一个类,通过值还是引用?

java基础