2010-10-15 39 views
3

此代碼:的Java:如何使用克隆()和怎麼樣的投檢查

class RawStringIterator { 
     java.util.Stack<State> stateStack = new java.util.Stack<State>(); 
     RawStringIterator(RawStringIterator i) { 
       stateStack = (java.util.Stack<State>) i.stateStack.clone(); 
     } 
     /* ... */ 
} 

給了我這樣的警告:

Type safety: Unchecked cast from Object to Stack<Utils.OperatorTree.RawStringIterator.State> 

我想我在這裏可以忽略警告。但是我想知道一般如何使用clone()?每次使用clone()時,我是否總是必須使用@SuppressWarnings("unchecked")?或者我應該始終做完全多餘的額外支票?

回答

11

如果你有選擇,最好是不根本沒有執行/使用clone(),因爲it is a broken API。只需實現/使用複製構造函數。

如果由於某種緊迫的原因,你必須使用clone()但可以改變其執行情況,考慮宣佈Stack<T>.clone()返回Stack<T>,而不是Object - 協變返回類型是合法的,因爲Java5中。

更新:如果有問題的Stackjava.util.Stack,考慮its Javadoc

LIFO堆棧操作的更完整,一致通過Deque接口和它的實現,應在使用提供喜歡這個班。

並且例如ArrayDeque提供了copy constructor

+0

'Stack '''java.util.Stack 'here。所以我不能在那裏更改任何聲明。 – Albert 2010-10-15 11:54:05

+0

@Albert,儘管你可能仍然可以切換到不同的集合 - 請參閱我的更新。 – 2010-10-15 11:57:57

+0

+1爲'Deque'。 – Bozho 2010-10-15 12:11:14

0

你別無選擇,只能忽略它。

雖然沒有直接的關係(因爲你不是在寫一個clone()法),在Java Generics FAQ此項目是一個很好的閱讀(一樣整個常見問題解答!)

2

這裏沒有辦法避免施放。 clone()返回Object,如果它是java.util.Stack,則不使用協變式返回類型。

如果這不是java.util.Stack,那麼請不要執行clone() - 確實很難做到這一點。改爲複製構造函數。

+0

你可以(也可以推薦)和你的'clone()'一起使用協變返回類型 - Effective Java 2nd Ed。第11項顯示了明確的例子。 – 2010-10-15 11:52:10

+0

是的,但java.util.Stack沒有。這是我的觀點。我將澄清 – Bozho 2010-10-15 11:53:49

+0

不,「java.util.Stack」沒有拷貝構造函數。否則,我會用它。 – Albert 2010-10-15 11:56:05

0

是的,每次使用clone()時都需要明確禁止警告。

這是您可能更喜歡使用複製構造函數而不是clone()(如果可用)的原因之一。

通過在你的代碼的方式,當使用RawStringIterator(RawStringIterator i)構造的stateStack第一初始化是不必要的:

class RawStringIterator { 
    Stack<State> stateStack = new Stack<State>(); 
    RawStringIterator(RawStringIterator i) { 
      stateStack = (Stack<State>) i.stateStack.clone(); 
    } 
    /* ... */ 
} 

你可能想刪除。