假设我有以下代码片段为一个小的随机游戏创建彩色蔬菜,我正在练习将对象属性从对象类中分离出来:
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&D开始做我自己的例子),我不知道为什么要第二次更改propertyList
不
影响之前在Maisie中设置的值。
我遵循了这本书提供的结构,但在第一次将其添加到列表之前,我为每个单独的蔬菜对象创建了一个新的HashMap。这本书表明这是不必要的,但没有深入到
为什么?
.
我所能看到的是,解释器在第二次在蔬菜构造函数中指定hashmap时,正在选择创建一个新的hashmap实例。但是
为什么?
?
它怎么知道我宁愿在那里有一个不同的HashMap,而不是重用第一个对象和。put()更改两种蔬菜的值?
第二个相关问题是。。。。如果我真的想让两种蔬菜共享完全相同的属性列表(相同的HashMap对象),我该怎么做?这真的应该是一个可怕的想法。。。为什么?我不知道自己在做什么,怎么会想要这个节目呢?
我的理解超出了“它与对象引用有关”的范畴。
谢谢你帮我弄清楚这件事。
要求的蔬菜等级:
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);
}
}
}