2017-05-26 20 views
1

我看到一个默认的setX函数只是使用X = _x,但是在Java中它不会仅仅是对_x对象的引用吗?爪哇 - 我应该在二传手使用新的()或不?

不应该用X = new X(_x)代替吗?

我真的找了个答案,还没有找到答案。

+1

“它不只是对_x对象的引用”是的。 “我不应该使用X = new X(_x)吗?”取决于a)'X'是否有这样的构造函数,b)你实际上需要一个新的实例(例如作为防御副本)。 –

+0

YourClass yourClass = new YourClass(); yourClass.setX(_x)。你可以发布你的代码? –

+0

如果这是您需要的,那么对现有对象实例的引用有什么问题?是否需要新实例取决于场景。 –

回答

3

要语义正确,_x不是一个对象,这是一个参数,它引用的对象。是的,你以后会X是引用的副本,所以它会指向同一个对象。

但通常这正是你想要达到的目标。每当你设置一个值时你都不想产生新的对象。而且你经常明确地希望它成为完全相同的对象。

只有当调用站点将其对象的版本视为私有属性时,才会负责生成和设置副本。

3

名称制定者暗示:设置字段。

该方法不叫storeCopyOf(),是吗?

当然你可以使用新的(如果相应的类提供了一个拷贝构造函数),但是在setter中这样做并不常见。如图所示,考虑到名称setX()与之通信的含义,这样做是非常具有误导性的。

2

我不应该用X = new X(_x)呢?

不,你不应该。您的API的用户期望完全设置给定的实例,而不是其副本。

如果它不符合您的需求,您可以通过抛出异常来验证此传入实例,但设置副本确实不清楚。

也许,你可能想通过使用这种方法从一个getter返回一个值。返回一个内部字段(引用类型)的副本是保持不变性的好技术。

1

我们使用setter(和getter)方法来实现encapsulation

例子:

private String myField; //"private" means access to this is restricted 

public String getMyField() 
{ 
    //include validation, logic, logging or whatever you like here 
    return this.myField; 
} 
public void setMyField(String value) 
{ 
    //include more logic 
    this.myField = value; 
} 

谁在使用你API S,将根据需要通过这些值,喜欢一个人:

obj.setMyField("myvalue"); 
1

如果x是一个基本类型,那么就没有必要使用复制构造函数重新创建值,因为其他位置的值更改不会影响本地副本。

如果要设置一个可变的(可更换)对象,但你不想让你的副本中更改,然后是你应该用你的二传手拷贝构造函数。不过,我会毫不犹豫地致电该设置,它更像是一个saveCopy(_x);