Java不安全或未检查的表达式:克隆arraylist
我在编译时遇到了未检查的表达式错误,发现有问题的行是Java不安全或未检查的表达式:克隆arraylist,java,compiler-errors,type-safety,Java,Compiler Errors,Type Safety,我在编译时遇到了未检查的表达式错误,发现有问题的行是 ArrayList<Integer> items = (ArrayList<Integer>) this.items.clone(); 我正在尝试执行对象的深度复制,因此我正在以上述方式克隆对象和数组列表的属性。如何修复此警告 我可以使用@SuppressWarningUnchecked,但这只是隐藏了问题,而我不希望出现任何问题 如果我通过循环所有元素来手动克隆,我认为会更慢 正确的方法是什么?使用新的ArrayL
ArrayList<Integer> items = (ArrayList<Integer>) this.items.clone();
我正在尝试执行对象的深度复制,因此我正在以上述方式克隆对象和数组列表的属性。如何修复此警告
我可以使用@SuppressWarningUnchecked,但这只是隐藏了问题,而我不希望出现任何问题
如果我通过循环所有元素来手动克隆,我认为会更慢
正确的方法是什么?使用新的ArrayListthis.items可以获得相同的行为。不管怎样,这都是肤浅的复制品
您可以使用新的ArrayListthis.items获得相同的行为。不管怎样,这都是肤浅的复制品
由于在Java API中引入泛型时需要向后兼容,因此在某些情况下无法使用强制转换和@SuppressWarningUnchecked
另外,请参阅了解为什么使用克隆时要小心:它会进行浅拷贝,这对灵长类来说很好,但对对象来说很危险。由于在Java API中引入泛型时需要向后兼容,因此在某些情况下无法使用强制转换和@suppressWarningUnchecked
另外,请参阅了解为什么使用克隆时要小心:它可以进行浅拷贝,这对灵长类动物来说是好的,但对对象来说是危险的。您说过您正在尝试进行深度拷贝,但正如前面所讨论的,我怀疑您是否能够使用克隆来实现这一点。因此,正如其他海报所说,使用克隆是一种更危险的方法,您将无法获得您一直在寻找的深度拷贝。您说过您正在尝试进行深度拷贝,但正如前面所讨论的,我怀疑您能否使用克隆来实现这一点。因此,正如其他海报所说,使用克隆是一种更危险的方法,您将无法获得您一直在寻找的深度副本。如果您的元素是整数,则执行深度副本实际上不是问题,因为您没有理由需要复制整数对象。只需使用新的ArrayListthis.items
但作为参考,克隆和ArrayList复制构造函数都不会执行深度复制。这只是因为您的元素类型不需要深度复制,这就满足了您的需要。如果您的元素是整数,执行深度复制实际上不是问题,因为没有理由需要复制整数对象。只需使用新的ArrayListthis.items
但作为参考,克隆和ArrayList复制构造函数都不会执行深度复制。只是因为您的元素类型不需要深度复制,这才满足了您的需要。整数是不可变的,所以是否进行深度复制无关紧要 使用java.util中的Collections实用程序类:
import java.util.Collections;
...
ArrayList<Integer> items = new ArrayList<Integer>(this.items.size());
Collections.copy(items, this.items);
整数是不可变的,所以是否进行深度复制并不重要 使用java.util中的Collections实用程序类:
import java.util.Collections;
...
ArrayList<Integer> items = new ArrayList<Integer>(this.items.size());
Collections.copy(items, this.items);
正如其他人指出的那样,克隆ArrayList并不克隆其元素。如果您想制作内容的深度副本,有一个巧妙的技巧:序列化和反序列化数组。这是因为ArrayList和Integer都实现了可序列化。但是,这并不能消除抑制未检查的转换警告的需要
// Write the object out to a byte array
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream out = new ObjectOutputStream(bos);
out.writeObject(this.items);
byte[] bytes = bos.toByteArray();
// Retrieve an input stream from the byte array and read
// a copy of the object back in.
ObjectInputStream in = new ObjectInputStream(
new ByteArrayInputStream(bytes));
ArrayList<Integer> items = (ArrayList<Integer>) in.readObject();
如果可以将整个对象声明为可序列化,则可以使用此操作而不是克隆操作来创建深度副本。另外,请参阅以获取避免从ByteArrayOutput流中复制字节的方法。正如其他人所指出的,克隆ArrayList不会克隆其元素。如果您想制作内容的深度副本,有一个巧妙的技巧:序列化和反序列化数组。这是因为ArrayList和Integer都实现了可序列化。但是,这并不能消除抑制未检查的转换警告的需要
// Write the object out to a byte array
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream out = new ObjectOutputStream(bos);
out.writeObject(this.items);
byte[] bytes = bos.toByteArray();
// Retrieve an input stream from the byte array and read
// a copy of the object back in.
ObjectInputStream in = new ObjectInputStream(
new ByteArrayInputStream(bytes));
ArrayList<Integer> items = (ArrayList<Integer>) in.readObject();
如果可以将整个对象声明为可序列化,则可以使用此操作而不是克隆操作来创建深度副本。另外,请参阅,了解避免从ByteArrayOutputStream复制字节的方法。可以将原语放入ArrayList中吗?我以为你只能放对象,最多只能放原语的包装器。@blahman重点是原语字段在克隆时是可以的,但是像ArrayList项这样的对象字段是麻烦的来源。哦……哎呀。完全错过了。对不起,Yuushi。我的错^^同样,谢谢@TedHopp=您可以在ArrayList中放置原语吗?我以为你只能放对象,最多只能放原语的包装器。@blahman重点是原语字段在克隆时是可以的,但是像ArrayList项这样的对象字段是麻烦的来源。哦……哎呀。完全错过了。对不起,Yuushi。我的坏^^也感谢@TedHopp=当然,没有必要制作整数对象的深度副本。当然,没有必要制作整数对象的深度副本。Arrays.copyOf不返回a
rrayList.Oops表示Collections.copy,而不是Arrays.copyOf.Arrays.copyOf不返回ArrayList.Oops表示Collections.copy,而不是Arrays.copyOf。