2014-09-25 37 views
2

在Java中,所有变量都是按值传递的。 对于对象, 这意味着我们通过对象的引用。 我很困惑以下情况。 假设我们有一个对象图。 一个对象包含另一个对象的字段引用, 该对象引用另一个对象,如:user.address.city。 在这里,我们有类User的实例, 该实例具有对类型为String - city的字段类Address的实例的引用。 现在让我们说我们有2个用户:Java中的对象和引用

User bob = new User(); 
User mary = new User(); 

假设对象“鲍勃”具有参考地址对象:

Address bobAddress = new Address(); 
bobAddress.setCity("New York"); 

bob.setAddress(bobAddress); 

比方说,玛丽和鲍勃开始在一个房子住在一起,他们有相同的地址, 没有问题:

mary.setAddress(bobAddress); 

现在玛丽和Bob引用一个地址对象。 但是有一天他们离婚和玛丽现在有另一个地址:

mary.getAddress().setCity("Boston"); 

在这里,我们有一个问题: 玛丽在她的地址改变的东西, 但她也改变了Bob的地址, 因为它们共享相同的参考。

以上所有文本都是我的尝试,以小规模描述一个大问题: 当我应该在将该对象的引用设置为另一个实例之前创建某个对象的副本(克隆)时? 是否存在一些规则或技术? 我知道有关这些对象的不可变对象(例如String,Integer等),我们不需要考虑这些问题,但是如果我有可变对象。 我应该如何与他们共事?

+0

你完全理解力学/语言。但是你说得对,你的*设计*会产生这个问题,因此不起作用。因此,我为什么提高了设计修正。 – djechlin 2014-09-25 20:28:15

回答

1

我认为你的想法是关闭的。

如果玛丽动了,这意味着她会去一个新的地址。尝试把它放到Java中。你只需要为Mary创建另一个地址。

国际海事组织,如果它是相同的对象,你永远不应该克隆相同的对象的分配。 (你可以进行一些处理计算)。

只是减少耦合,并有mary.setAddress(字符串streeName,字符串城市,字符串状态)。通常一个地址的城市不应该改变,因为街道不能从一个城市移动到另一个城市,因此你甚至不应该有一个setCity()公共方法。

7

您的问题表示Address类的设计不好。

Address类代表一个地理位置并且是固定的。 当个人移动时, 地理位置不变;相反, 个人居住的地理位置变化。

删除Address的setter并将其设置为不可变对象。 当一个人移动, 必须执行下列操作之一:

  1. 如果个人与另一个人分享现有的地址(对象实例),然后分配给现有的参考。
  2. 如果个人移动到一个新的地址(一个新的对象实例),然后分配地址到一个新的地址实例。
+0

这是正确的答案。 – djechlin 2014-09-25 20:27:06

+0

可能更好措辞比我的答案+1 – 2014-09-25 20:27:56

+1

@Ajk_P你的答案是正确的,但你可能还没有与不变性的概念工作。这绝对是解决这个问题的方法。在高度并发和功能性编程中,这是非常重要的。当不改变的事物(如地址的城市或日期年份)不会在代码中更改时,生活变得更容易。 – djechlin 2014-09-25 20:29:29