2013-02-11 37 views
4

我在我的主要Recipe recipeOne = new Recipe("Pepperoni Pizza");深对象数组实例的复制,爪哇

这个对象做出一个目的是定义在这里建造这个对象数组的一个实例!

public class Recipe implements Cloneable{ 

String Name; 

final int INGREDIENT_ARRAY_MAX = 10; 

Ingredient Recipe[] = new Ingredient[INGREDIENT_ARRAY_MAX]; 

public Recipe(String name){ 

    Name = name; 

} 

所以我期待,使这个对象的深拷贝和该行Recipe ressippi = (Recipe) recipe.clone();并在这里向我发送!

public Object clone(){ 

    Recipe cloneRec = new Recipe(Name); 

    return cloneRec; 

} 

我知道这是目前一个浅拷贝,因为该方法只传递引用,所以如果我是试图在我的新目标,这是recipeOne的克隆一个名称的改变...这将改变两者的他们名。很显然,我不想那样,我对此很遗憾,任何人都可以帮忙吗?

编辑:@Rohit耆那教

无论我的食谱类,以及我的阶级成分(配方数组保存对象)具有的toString方法和食谱呼吁成分以打印这一切在一个可爱的小格式。当我把它叫做我的“recipeOne”对象(一个叫辣椒比萨饼)时,我得到了“意大利辣香肠比萨:1.0磅面团,8.0盎司酱汁,10.0盎司奶酪”

然后我着手制作物品ressippi并将其设置为recipeOne的克隆,所以这里都很好...然后我将ressippi的名称更改为“Pineapple Pizza”,并且打印出良好的效果,但它不打印recipeOne存储的3个配料对象,这是假定要做的!

+3

看到这个答案: [链接](http://stackoverflow.com/a/64066/1809603) – 2013-02-11 09:51:38

+0

怎么样'新的String (姓名)'? – 2013-02-11 09:57:50

回答

3

添加一个拷贝构造函数的配方类,它创建配方的新实例并复制原始配方中的所有字段。

食谱。java的

public class Recipe implements Cloneable { 

    String name; 

    final int INGREDIENT_ARRAY_MAX = 10; 

    Ingredient[] ingredients = new Ingredient[INGREDIENT_ARRAY_MAX]; 

    public Recipe(String name) { 
     this.name = name; 
    } 

    //Copy Constructor 
    private Recipe(Recipe recipe){ 
     this.name = recipe.name; 
     for(int x = 0; x < recipe.ingredients.length; x++){ 
      this.ingredients[x] = recipe.ingredients[x]; 
     } 
    } 

    public static Recipe newInstance(Recipe recipe){ 
     return new Recipe(recipe); 
    } 

    //Debug Method 
    public static void printRecipe(Recipe recipe){ 
     System.out.println("Recipe: " + recipe.name); 
     for(Ingredient i:recipe.ingredients){ 
      if(i != null && i.getName() != null){ 
       System.out.println("Ingredient: " + i.getName());   
      } 
     } 
    } 

    //Test Method 
    public static void main(String[] args) { 
     Recipe recipe = new Recipe("Chicken Soup"); 
     recipe.ingredients[0] = new Ingredient("Chicken"); 
     recipe.ingredients[1] = new Ingredient("Broth"); 

     Recipe copy = new Recipe(recipe); 
     copy.ingredients[2] = new Ingredient("Rice"); 
     copy.name = "Chicken Rice Soup"; 

     printRecipe(recipe); 
     printRecipe(copy); 
     System.out.println(recipe == copy); 
     System.out.println(recipe.ingredients == copy.ingredients); 
    } 
} 

Ingredient.java

public class Ingredient { 

    private String name; 

    public Ingredient(String name){ 
     this.name = name; 
    } 

    public String getName() { 
     return name; 
    } 


    public void setName(String name) { 
     this.name = name; 
    } 
} 
+0

已经很老了,但我认为“this.ingredients [x] = recipe.ingredients [x];”不应该在**深层复制**中完成。您需要再次对每个元素进行深层复制。 – 2017-01-24 00:59:22

1

正如你发现的那样,实现Cloneable实际上并没有克隆该对象。您必须明智地实施clone()方法,如果您想要深度复制,那就是您应该实施的方法。

现在,创建一个新的Recipe对象具有相同的Name属性是相当好的。之后更改新对象的名称也很好,它不会更改第一个对象的名称,因为java String是不可变的。

您可能想看看commons-beanutils软件包,该软件包提供了克隆对象的方便代码。

最后,至于“...只传递引用...”,你应该阅读例如。 thisthis线程。

干杯,

1

序列化它!看看这里的deepClone函数:http://www.avajava.com/tutorials/lessons/how-do-i-perform-a-deep-clone-using-serializable.html

对字符串的其他回复是不可变的,当然是真的,但是你试图用String例子描述的问题只是一个坏例子;复杂的对象,如配料数组仍然是通过引用复制。

另外:改变你的阵列的名称,以便它不匹配类名(=混乱):

Ingredient Recipe[] = new Ingredient[INGREDIENT_ARRAY_MAX];