Глубокая копия экземпляра массива объектов, Java
У меня есть объект, сделанный в моей главной 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...it изменил бы оба их имени. Очевидно, что я не хочу что, я совсем запутался в этом, может кто-нибудь помочь?
EDIT:@Rohit Джайн
Как мой класс рецептов, так и мой класс ингредиентов (объекты, которые содержит массив рецептов) имеют методы toString и рецепты, вызывающие ингредиенты, чтобы распечатать все это в хорошем маленьком формате. Когда я называю его на моем объекте" recipeOne "(который называется пицца Пепперони), я получаю "пицца Пепперони: 1,0 фунта теста, 8,0 унций соуса, 10,0 унций сыра"
Затем я приступаю к созданию объекта ресиппи и установил, что клон recipeOne, так что все хорошо отсюда...затем я меняю имя ressippi на "ананасовая Пицца", и это печатает прекрасно, но он не печатает 3 объекта ингредиента, которые recipeOne хранит, что он должен делать!
3 ответа:
Добавьте конструктор копирования в класс 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); } }
Ингредиент.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; } }
Как вы уже выяснили, реализация
Теперь создание нового объектаCloneable
на самом деле не клонирует объект. Вы должны будете реализовать методclone()
разумно, и если вы хотите глубокую копию, это то, что вы должны реализовать.Recipe
с тем же атрибутомName
вполне нормально. И изменение имени для нового объекта после этого также вполне нормально, это не изменит имя первого объекта, поскольку javaString
неизменяемы.Возможно, вы захотите взглянуть на commons-beanutils пакет, который предоставляет удобный код для клонирования объектов.
Наконец, что касается "...только передает ссылки...- ты бы почитал, например. эта и Эта нить.
Ура,
Сериализуйте его! Взгляните на функцию deepClone, как показано здесь: http://www.avajava.com/tutorials/lessons/how-do-i-perform-a-deep-clone-using-serializable.html
Другие ответы на неизменяемые строки, конечно, верны, но проблема, которую вы пытались описать с помощью примера строки, была просто плохим примером; более сложные объекты, такие как массив ингредиентов, все еще копируются по ссылке.
Также: измените имя массива так, чтобы оно не соответствовало имя класса (=путаница):
Ingredient Recipe[] = new Ingredient[INGREDIENT_ARRAY_MAX];