我正在尝试以与克隆单数链表相同的方式克隆循环链表,但遇到了麻烦。我试图在公共方法clone()中只留下调用受保护方法clone()的行,但程序仍然抛出错误。public static void main(String[] args) throws CloneNotSupportedException { CircularlyLinkedList<String> circularList = new CircularlyLinkedList<String>(); circularList.addFirst("1"); circularList.addLast("2"); circularList.addLast("3"); circularList.addLast("4"); CircularlyLinkedList<String> newList = new CircularlyLinkedList<String>(); newList= circularList.clone(); System.out.println(newList); }@SuppressWarnings("unchecked")public CircularlyLinkedList<E> clone() throws CloneNotSupportedException { // always use inherited Object.clone() to create the initial copy CircularlyLinkedList<E> other = (CircularlyLinkedList<E>) super.clone(); // safe cast if (size > 0) { // we need independent chain of nodes other.head = new Node<>(head.getElement(), null); Node<E> walk = head.getNext(); // walk through remainder of original list Node<E> otherTail = other.head; // remember most recently created node while (walk != null) { // make a new node storing same element Node<E> newest = new Node<>(walk.getElement(), null); otherTail.setNext(newest); // link previous node to this one otherTail = newest; walk = walk.getNext(); } } return other;}此代码在使用单链表时有效。预期的输出是打印两次的链表,但实际输出的是抛出的异常“CloneNotSupported”。请注意,当 clone() 返回空列表时,程序不会抛出此异常。
1 回答

智慧大石
TA贡献1946条经验 获得超3个赞
这是问题所在,我认为:
CircularlyLinkedList<E> other = (CircularlyLinkedList<E>) super.clone();
现在你还没有告诉我们超类CircularlyLinkedList
是什么,但证据是:
它不实现
Cloneable
标记接口。它不会覆盖
clone
它继承自的方法Object
。
使用该组合,super.clone()
将抛出CloneNotSupportedException
. 这在javadoc中进行了解释。
真正的问题是你为什么打电话super.clone()
?
如果您这样做是因为超类具有需要在您正在创建的克隆中复制的状态,那么它(超类)必须提供某种克隆自身的方式;即它需要执行上述操作之一……或提供“复制构造函数”或类似内容。
如果您这样做只是为了使打字工作,那么您可能应该这样做:
CircularlyLinkedList<E> other = new CircularlyLinkedList<>();
构造函数(private
如果需要的话可以)创建一个实例,您可以开始填写。请注意,这是类型安全的。
我注意到这条评论:
// always use inherited Object.clone() to create the initial copy
如果它的意思是永远适用于这个类,那么只需修复它以匹配您实际所做的事情。请记住,只有在超类是可克隆的情况下您才能做到……目前还不是!
如果打算记录在所有情况下都这样做 是“最佳实践”(或其他东西;请参阅this ),那是完全错误的:
正如我解释的那样,你不能在所有情况下都这样做。
虽然有人认为使用另一种方法来复制超类状态可能是不可取的,但子类有权在 OO 设计中对其超类做出假设。
此外,打电话给
super.clone()
你是在做一个假设……这clone()
会奏效!
添加回答
举报
0/150
提交
取消