我怎样才能确定何时可以重复使用对象?

时间:2018-01-24 15:52:10

标签: java object reference

假设我有以下代码片段为一个小型随机游戏创建彩色蔬菜我正在练习将对象属性从对象类中分离出来:

    List<Vegetable> vegList = new ArrayList<Vegetable>();

    Map<MyProperty, Object> propertyList = new HashMap<MyProperty, Object>();

    propertyList.put(MyProperty.COLOR, "#0000BB");
    propertyList.put(MyProperty.TYPE, MyType.VEGETABLE);
    propertyList.put(MyProperty.COMMONNAME, "Potato");

    vegList.add(new Vegetable("Maisie", propertyList));

    propertyList.put(MyProperty.COLOR, "#00FF00");
    propertyList.put(MyProperty.COMMONNAME, "Poisonous Potato");

    vegList.add(new Vegetable("Horror", propertyList));

我在这样做的时候意识到了(基本上从Head First OOA&amp; D开始我自己的例子)我不知道为什么第二次更改propertyList 不会影响之前设置的值美施

我遵循了本书提供的结构,但第一次我为每个单独的Vegetable对象创建了一个新的HashMap,然后将其添加到列表中。这本书表明这是不必要的,但没有进入为什么

我只能看到解释器在第二次在Vegetable构造函数中指定时,可以选择创建一个新的hashmap实例。但为什么

我怎么知道我宁愿在那里使用不同的HashMap,而不是重用第一个对象和.put()来更改两个蔬菜的值?

第二个相关的问题是......我是否真的要让2个蔬菜共享完全相同的属性列表(相同的HashMap对象),我该怎么做?这应该是一个可怕的想法......为什么?怎么会想要这个节目我只是不知道我在做什么?

我的理解超越了#34;它与对象引用有关&#34;。

感谢您帮我解决此问题。

要求的蔬菜类:

public class Vegetable {
    public VegetableSpec characteristics;
    public String name;

    public Vegetable(String name, Map<MyProperty, Object> propertyList) {
        this.name = name;
        this.characteristics = new VegetableSpec(propertyList);
    }

    public void display() {
        System.out.printf("My name is %s!\n", this.name);
        for (Entry<MyProperty, Object> entry : characteristics.properties.entrySet()) {
            System.out.printf("key: %s, val: %s\n", entry.getKey().toString(), entry.getValue().toString());
        }
    }
}

...让我再次看看VegetableSpec(我把它放进去是因为这本书使用了一个单独的Spec类,但我不明白为什么除了添加搜索功能之外还有必要;现在我觉得我看到它了做两件事,一件是防御性复制!):

public class VegetableSpec {
    Map<MyProperty, Object> properties;

    public VegetableSpec(Map<MyProperty, Object> properties) {
        if (properties == null) {
            // return a null = bad way to signal a problem
            this.properties = new HashMap();
        } else {
            // correction above makes it clear this isn't redundant
            this.properties = new HashMap(properties);
        }

    }

}

1 个答案:

答案 0 :(得分:1)

听起来像蔬菜的构造函数正在制作defensive copy。这通常是一个好主意,以防止任何人以对象的设计者不想要的方式更改对象。你应该(几乎)总是制作防御性副本。

  

我想让2个蔬菜共享完全相同的属性列表(相同的HashMap对象),我该怎么做?

传入相同的哈希映射,并忽略它作为防御副本的事实,对于您作为消费者而言并不重要。