2016-03-04 66 views
0

我對Java比較陌生,因此是個問題。爲什麼Java在轉換對象時會強制轉換對象,以及編譯器究竟發生了什麼。這是我的簡單水平定單搜索的代碼。在Java中顯式對象轉換

void LevelOrder(Node root) 
    { 
     Queue<Node> Q = new LinkedList(); 
     Q.add(root); 
     while(!Q.isEmpty()){ 
      Node p = Q.poll(); 
      System.out.print(p.data+ " "); 
      if(p.left != null) Q.add(p.left); 
      if(p.right != null) Q.add(p.right); 
     } 


    } 

當我在黑客等級提供的基於Web的IDE上運行此代碼時,它會編譯但會給我下面的警告。

Note: Solution.java uses unchecked or unsafe operations. 
Note: Recompile with -Xlint:unchecked for details. 

當我通過改變poll該線投射的節點對象,

Node p = (Node)Q.poll(); 

它仍然彙編表示相同的警告。

但是,在我的IntelliJ IDE中,第一個代碼甚至不會編譯,只有第二個代碼(使用顯式轉換)編譯。

有人可以解釋這裏究竟發生了什麼。 除了解決錯誤,有人可以解釋爲什麼一個編譯器讓這行代碼編譯,而另一個沒有沒有明確的轉換。

Node p = Q.poll(); 
+0

在'LinkedList',即'LinkedList <>'之後需要'''''。 –

+0

您需要詳細瞭解仿製藥 – Ramanlfc

+0

爲什麼要投票。如果世界上的每個人都知道一切,那麼就不會有SO。 – Zeus

回答

3
new LinkedList(); 

這是一個raw-typed集 - 編譯器不知道是什麼類型的元素都在它(儘管事實上在它沒有)。

這樣,當你嘗試將其分配到只能容納Node類型的元素的引用:

Queue<Node> Q = new LinkedList(); 

那麼編譯器無法知道這是否是安全與否。

的修復很簡單:告訴編譯器元素的類型:7+

Queue<Node> Q = new LinkedList<Node>(); 

它可以在Java是更簡單:

Queue<Node> Q = new LinkedList<>(); 

在這種情況下,編譯器推斷鍵入爲<Node><>被稱爲「鑽石記號」;它不能在所有情況下使用,但可以在像這樣的賦值語境中使用。

+0

我已經稍微更新了我的問題,能否相應更新您的答案。謝謝。 – Zeus

+0

我無法在android應用程序中看到編輯歷史記錄 - 更改是什麼? –

+0

基於Web的IDE允許沒有顯式強制轉換的行編譯,而IntelliJ不行。這是尚未回答的部分。謝謝。 – Zeus

1

原因是這一行:

Queue<Node> Q = new LinkedList(); 

,如果你將其更改爲

Queue<Node> Q = new LinkedList<Node>(); 

警告disapers。

在第一種情況下,您在第二個列表Node中列出了Object,

這在編譯時很重要。稍後在執行期間,所有集合都是Object類型。如果您將其他類型的對象添加到列表中,您將在運行時得到一個ClassCastException。 (在情況下,編譯器無法檢測到您添加錯誤類型的對象)

由於Java 1.7有可能只寫

Queue<Node> Q = new LinkedList<>(); 

編譯器現在是足夠聰明的知道你的意思Node

1

修復與宣稱喜歡這裏一個LinkedList後加入<>這一行:

Queue<Node> Q = new LinkedList<>(); 

或者你也可以做這樣的位置:在JDK 7菱形操作符可以用來

Queue<Node> Q = new LinkedList<Node>(); 

注而不是顯式的類型參數。所以我更喜歡第一種方式。