I have an object made in my main Recipe recipeOne = new Recipe("Pepperoni Pizza");
This object is an instance of this Object Array defined and constructed here!
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;
}
So I am looking to make a deep copy of this object with the line Recipe ressippi = (Recipe) recipe.clone();
and it sends me here!
public Object clone(){
Recipe cloneRec = new Recipe(Name);
return cloneRec;
}
I know this is currently a shallow copy because the method only passes references, so if I was to attempt a name change on my new Object that was a clone of recipeOne...it would change both of their names. Obviously I do not want that, I'm fairly lost on this, can anyone help?
EDIT:@Rohit Jain
Both my Recipe class as well as my Ingredient class (the objects the recipe array holds) have toString methods and recipes calls on ingredients in order to print it all out in a nice little format. When I call it on my "recipeOne" object (the one called pepperoni pizza) i get "Pepperoni Pizza: 1.0 Pounds of Dough, 8.0 Ounces of Sauce, 10.0 Ounces of Cheese"
Then I proceed to make the object ressippi and set that to the clone of recipeOne, so all good from here...then I change ressippi's name to "Pineapple Pizza" and that prints out fine but it doesnt print the 3 ingredient objects that recipeOne stored, which it is suppose to do!
So any changes to the copied array will reflect in the original. Java cloning is an example of a shallow copy. A deep copy is the one wherein we need a complete copy of the object so that when we clone or copy that object, it is an independent copy.
It just copies the source element values into the target elements. Again we have the same effect as a deep copy at the expense of an operation needing much less code than for a deep copy. So Arrays. copyOf(..) is a 'cheap' deep copy for both primitive and 1-D Object arrays.
Add a copy constructor to the recipe class, which creates a new instance of recipe and copies all of the fields from an original recipe.
Recipe.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;
}
}
As you have found out, implementing the Cloneable
doesn't actually clone the object. You'll have to implement the clone()
method sensibly, and if you want a deep copy, that's what you should implement.
Now, creating a new Recipe
object with the same Name
attribute is quite OK. And changing the name for the new object afterwards is also quite okay, it won't change the name of the first object as java String
's are immutable.
You may want to have a look at the commons-beanutils package, which provides handy code for cloning objects.
Finally, as for "...only passes references..." you should read eg. this and this thread.
Cheers,
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With