Java 深度复制对象数组
我对Java还是相当陌生的,现在我正在尝试复制菜单。我想我已经做了一点,创建了一个包含新菜单项的新菜单对象。MenuItems是另一个类,具有两个字符串变量和一个双变量,即itemName和itemDescription以及itemPrice。所以我试图将原始菜单项的三个变量的内容复制到菜单项副本中,但我不知道如何复制。我一直在试图将克隆副本的名称设置为原始名称Java 深度复制对象数组,java,arrays,clone,Java,Arrays,Clone,我对Java还是相当陌生的,现在我正在尝试复制菜单。我想我已经做了一点,创建了一个包含新菜单项的新菜单对象。MenuItems是另一个类,具有两个字符串变量和一个双变量,即itemName和itemDescription以及itemPrice。所以我试图将原始菜单项的三个变量的内容复制到菜单项副本中,但我不知道如何复制。我一直在试图将克隆副本的名称设置为原始名称 public class Menu { Menu() { } final int maxItem
public class Menu
{
Menu()
{
}
final int maxItems = 50;
MenuItem[] food = new MenuItem[maxItems + 1];
public Object clone()
{
Menu menuClone = new Menu();
MenuItem[] foodClone = new MenuItem[maxItems + 1];
for(int i = 1; i <= maxItems + 1; i++)
{
foodClone[i] = new MenuItem();
foodClone[i] = food[i].setItemName();
}
}
你就快到了,你已经:
foodClone[i] = food[i].setItemName();
您可能想要(除了MenuItem的其他变量)
但是,最好使用克隆方法或复制构造函数(嗯,)
我更喜欢使用复制构造函数,例如:
MenuItem(MenuItem menuItemToClone)
{
this.name = menuItemToClone.name;
this.descrip = menuItemToClone.descrip;
this.price = menuItemToClone.price;
}
那么你就做:
foodClone[i] = new MenuItem(food[i]);
尽管前面有一些建议,克隆只提供了一个浅拷贝 深度复制问题的常见解决方案是使用Java对象序列化(JOS)。想法很简单:使用JOS的ObjectOutputStream将对象写入数组,然后使用ObjectInputStream重新构建对象的副本。结果将是一个完全不同的对象,具有完全不同的引用对象。JOS负责所有细节:超类字段、跟踪对象图以及处理对图中相同对象的重复引用。图3显示了一个实用程序类的初稿,该实用程序类使用JOS制作深度副本
import java.io.IOException;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectOutputStream;
import java.io.ObjectInputStream;
/**
* Utility for making deep copies (vs. clone()'s shallow copies) of
* objects. Objects are first serialized and then deserialized. Error
* checking is fairly minimal in this implementation. If an object is
* encountered that cannot be serialized (or that references an object
* that cannot be serialized) an error is printed to System.err and
* null is returned. Depending on your specific application, it might
* make more sense to have copy(...) re-throw the exception.
*
* A later version of this class includes some minor optimizations.
*/
public class UnoptimizedDeepCopy {
/**
* Returns a copy of the object, or null if the object cannot
* be serialized.
*/
public static Object copy(Object orig) {
Object obj = null;
try {
// Write the object out to a byte array
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream out = new ObjectOutputStream(bos);
out.writeObject(orig);
out.flush();
out.close();
// Make an input stream from the byte array and read
// a copy of the object back in.
ObjectInputStream in = new ObjectInputStream(
new ByteArrayInputStream(bos.toByteArray()));
obj = in.readObject();
}
catch(IOException e) {
e.printStackTrace();
}
catch(ClassNotFoundException cnfe) {
cnfe.printStackTrace();
}
return obj;
}
}
不幸的是,这种方法存在一些问题:
来源:如果要克隆对象,我建议尝试使用
clone()
方法。您必须正确重写clone
对象并实现可克隆..或简单地创建一个复制构造函数。。还有小费。。java中的数组是基于0的。。所以第一个元素是数组[0],而不是[1]4。Java序列化向外界公开私有状态,并允许在读回对象时违反不变量。
foodClone[i] = new MenuItem(food[i]);
import java.io.IOException;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectOutputStream;
import java.io.ObjectInputStream;
/**
* Utility for making deep copies (vs. clone()'s shallow copies) of
* objects. Objects are first serialized and then deserialized. Error
* checking is fairly minimal in this implementation. If an object is
* encountered that cannot be serialized (or that references an object
* that cannot be serialized) an error is printed to System.err and
* null is returned. Depending on your specific application, it might
* make more sense to have copy(...) re-throw the exception.
*
* A later version of this class includes some minor optimizations.
*/
public class UnoptimizedDeepCopy {
/**
* Returns a copy of the object, or null if the object cannot
* be serialized.
*/
public static Object copy(Object orig) {
Object obj = null;
try {
// Write the object out to a byte array
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream out = new ObjectOutputStream(bos);
out.writeObject(orig);
out.flush();
out.close();
// Make an input stream from the byte array and read
// a copy of the object back in.
ObjectInputStream in = new ObjectInputStream(
new ByteArrayInputStream(bos.toByteArray()));
obj = in.readObject();
}
catch(IOException e) {
e.printStackTrace();
}
catch(ClassNotFoundException cnfe) {
cnfe.printStackTrace();
}
return obj;
}