我正在嘗試以與克隆單數鏈表相同的方式克隆循環鏈表,但遇到了麻煩。我試圖在公共方法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
提交
取消