Java 不安全或未经检查的表达式:克隆数组列表

发布于 2024-12-27 16:59:25 字数 329 浏览 1 评论 0原文

我在编译时遇到未经检查的表达式错误,并发现有问题的行是

ArrayList<Integer> items = (ArrayList<Integer>) this.items.clone();

我正在尝试执行对象的深层复制,因此我以上述方式克隆对象和数组列表的属性。我该如何解决这个警告?

  • 我可以使用 @SuppressWarnings("unchecked") 但这只是隐藏了问题(尽管我期望没有)
  • 如果我通过循环遍历所有元素来手动克隆它会更慢我认为

正确的方法是什么这样做?

I got the unchecked expression error when compiling and found the offending line to be

ArrayList<Integer> items = (ArrayList<Integer>) this.items.clone();

I am trying to perform a deep copy of my object so I am cloning a property of the object and array list in the above manner. How can I fix this warning?

  • I could use @SuppressWarnings("unchecked") but that is just hiding the problem (tho I expect none)
  • If I clone manually by looping through all elements to it will be slower I think

Whats the correct way of doing this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

月下客 2025-01-03 16:59:25

如果您的元素是整数,则执行“深层复制”实际上不是问题,因为没有理由需要复制整数对象。只需使用new ArrayList(this.items)

但作为参考,clone() 和 ArrayList 复制构造函数都不会执行深层复制。只是因为您的元素类型不需要深度复制,这才满足您的需求。

If your elements are Integers, performing a "deep copy" really isn't an issue, since there's no reason why you would need to copy an Integer object. Just use new ArrayList<Integer>(this.items).

But for reference, neither clone() nor the ArrayList copy constructor will do a deep copy. It's only because your element types don't need deep copying that this satisfies your needs.

岛徒 2025-01-03 16:59:25

您可以使用 new ArrayList(this.items) 获得相同的行为。但无论如何,这都是一个复制。

API

You can get the same behavior with new ArrayList<Integer>(this.items). Either way, though, it's a shallow copy.

API

挖鼻大婶 2025-01-03 16:59:25

整数是不可变的,因此是否进行深复制并不重要。

使用 java.util 中的 Collections 实用程序类:

import java.util.Collections;
...
ArrayList<Integer> items = new ArrayList<Integer>(this.items.size());
Collections.copy(items, this.items);

Integers are immutable, so it doesn't matter if you make a deep copy or not.

use the Collections utility class in java.util:

import java.util.Collections;
...
ArrayList<Integer> items = new ArrayList<Integer>(this.items.size());
Collections.copy(items, this.items);
空城之時有危險 2025-01-03 16:59:25

由于向 Java API 引入泛型时需要向后兼容,因此在某些情况下无法使用强制转换和 @SuppressWarnings("unchecked")。

另外,请参阅此处了解原因clone() 用法应谨慎使用:它执行浅复制,这对于基元来说很好,但对于对象来说很危险。

Because of the backwards compatibility required when they introduced generics to the Java API, there's no way around using casting and @SuppressWarnings("unchecked") in some situations.

Also, see here for a reason why clone() usage should be used with care: it does a shallow copy, which is fine for primatives, but is dangerous with objects.

南冥有猫 2025-01-03 16:59:25

您说过您正在尝试进行深层复制,但正如所讨论的此处,我怀疑您是否能够使用 clone() 来做到这一点。因此,就像其他发帖者所说的那样,使用clone()是一种更加危险的方法,并且您将无法获得您一直在寻找的深层副本。

You've said you're trying to do a deep copy, but as discussed here, I doubt you'll be able to do that using clone(). So, like the other posters have said, it is a somewhat more hazardous method to use clone() and you won't be able to get the deep copy you've been looking for.

情何以堪。 2025-01-03 16:59:25

正如其他人指出的那样,克隆 ArrayList 并不会克隆其元素。如果您想对内容进行深层复制,有一个巧妙的技巧:序列化和反序列化数组。 (这是有效的,因为 ArrayListInteger 都实现了 Serialized。)但是,这并不能消除抑制未经检查的转换警告的需要。

// 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 中复制字节。

As others have pointed out, cloning the ArrayList does not clone its elements. If you want to make a deep copy of the contents, there's a neat trick: serialize and deserialize the array. (This works because ArrayList and Integer both implement Serializable.) However, this doesn't get rid of the need to suppress unchecked conversion warnings.

// 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();

If your entire object can be declared Serializable, you could use this instead of a clone operation to make your deep copy. Also, see this article for a way to avoid the expense of copying the bytes out of the ByteArrayOutputStream.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文