2017-10-06 22 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支持的更简单的形式。这些转变是不可逆转的。