2017-10-06 27 views
-3

是否有人可以幫助確定哪些是與下面的代碼的問題......爲什麼是有問題編制的變量「i $」爲什麼變量的範圍有問題?

下面是代碼....

private void handlePendingFilesForPreviousCheckpoints(Map<Long, List<String>> pendingFilesPerCheckpoint) { 
     LOG.debug("Moving pending files to final location on restore."); 
     Set<Long> pastCheckpointIds = pendingFilesPerCheckpoint.keySet(); 
     Iterator i$ = pastCheckpointIds.iterator(); 

     while(i$.hasNext()) { 
      Long pastCheckpointId = (Long)i$.next(); 
      Iterator i$ = ((List)pendingFilesPerCheckpoint.get(pastCheckpointId)).iterator(); 

      while(i$.hasNext()) { 
       String filename = (String)i$.next(); 
       Path finalPath = new Path(filename); 
       Path pendingPath = this.getPendingPathFor(finalPath); 

       try { 
        if(this.fs.exists(pendingPath)) { 
         LOG.debug("Restoring BucketingSink State: Moving pending file {} to final location after complete checkpoint {}.", pendingPath, pastCheckpointId); 
         this.fs.rename(pendingPath, finalPath); 
        } 
       } catch (IOException var10) { 
        LOG.error("Restoring BucketingSink State: Error while renaming pending file {} to final path {}: {}", new Object[]{pendingPath, finalPath, var10}); 
        throw new RuntimeException("Error while renaming pending file " + pendingPath + " to final path " + finalPath, var10); 
       } 
      } 
     } 

    } 

即使i$的大括號...它說,該變量i$在範圍已經定義第二次內部定義....

有人可以幫我解決這個問題......並且明白什麼是在上面的代碼中,變量i $是錯誤的。

非常感謝。

+0

*「幫我解決這個問題」*將內部變量命名爲別的東西。什麼是不明顯的? – Andreas

+0

爲什麼你使用迭代器while循環,而不是更容易增強'for'循環?例如。 (longCheckCheckpointId:pendingFilesPerCheckpoint.keySet()){...}'---另外,不要使用* raw *泛型,即不​​要使用'Iterator',但在外層循環中使用'Iterator ' 。 – Andreas

+0

@Andreas當然,但是,正如我從其他類複製這塊代碼..在那裏我觀察員沒有問題..但爲什麼它在我的課上創建問題。你可以在這方面分享一些意見。非常感謝。 – Raja

回答

2

變量的作用域是定義它的(整個)塊,當然包括聲明塊中的所有子塊。

要解決該問題,請使用不同的變量名稱。

+0

非常感謝@Bohemian的輸入,但是想知道,爲什麼這會造成問題......因爲我從其他類複製了這種方法,並且工作正常......但是我的問題是......我可以請你解釋一下? – Raja

+0

兩個嵌套的迭代器循環。你不能刪除其中的一個。 – Andreas

+0

想在我的第二個評論中提出問題,然後在你的回答中,即使用增強for循環。 – Andreas

-1

一個簡單的(但可能不是最好的)解決方案是隻調用內部迭代器像ir或其他東西。

Ex。此行更改:​​ Iterator i$ = ((List)pendingFilesPerCheckpoint.get(pastCheckpointId)).iterator();

到這樣的事情: Iterator ir = ((List)pendingFilesPerCheckpoint.get(pastCheckpointId)).iterator();

+0

重複的答案。 [已包含](https://stackoverflow.com/a/46614507/5221149)。 – Andreas

0

你的評論是:

,但想知道,爲什麼這是創造的問題...我複製其他類此方法這是工作正常...但我的創造問題....你能請解釋

行你好實際上的確是你反編譯了一個類,並將反編譯的代碼複製到你的源代碼中。

該方法通常不起作用。你的是一個沒有奏效的例子。

典型的Java反編譯器的設計目標是將編譯後的代碼翻譯成程序員可以編寫的東西讀取。上面反編譯的代碼滿足這個要求。閱讀上述內容的典型Java程序員將會理解原始代碼試圖做什麼。

然而,有一對夫婦的非目標的反編譯:

  1. 它不是重現原始源代碼的目標。 (這在數學上是不可能的!)

  2. 這是不是一個目標,產生的風格是「最佳實踐」的代碼。由於多種原因,這是不切實際的。 (首先,人們無法就最佳做法達成一致!)

  3. In不是生成始終可編譯的代碼的目標。對於尚未被混淆的字節碼這可能是可能的,但:

    • 真的很難覆蓋邊緣的情況下,
    • 也不可能證明你已覆蓋的所有邊緣案例
    • 以及您需要支持的代碼集的編譯器總是在不斷增長。

這是什麼意思在實踐中?

在實踐中的代碼由反編譯器產生的通常是可讀性,可能編譯,但是:

  • 您可能需要更正編譯錯誤
  • 的代碼是不是作爲原始源代碼可維護
  • 該代碼不適合用作如何編程的示例。

1 - 但是,如果字節碼已經被混淆,全盤皆輸。混淆的目的是使難於反編碼和/或理解反編譯的代碼。

2 - 首先,編譯代碼時,編譯器會丟棄所有源代碼註釋和(通常)本地變量的名稱。然後它將諸如增強循環,內部類和lambdas等各種構造轉換爲JVM支持的更簡單的形式。這些轉變是不可逆轉的。