繁体   English   中英

为什么变量的范围有问题?

[英]why is there an issue with scope of the variable?

有人可以帮助确定以下代码的问题......以及为什么在编译变量“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$ 有什么问题。

非常感谢。

变量的范围是定义它的(整个)块,当然包括声明块中的所有子块。

要解决此问题,请使用不同的变量名称。

你评论了这个:

但想知道,为什么这会产生问题......因为我从其他类复制了这个方法并且工作正常......但我的正在产生问题......你能解释一下吗

好的,您实际上所做的是反编译一个类并将反编译的代码复制到您的源代码中。

这种方法往往行不通。 而你的就是一个没有奏效的例子。

典型 Java 反编译器的设计目标是将编译后的代码翻译成程序员可以阅读的内容 上面的反编译代码满足了这一点。 阅读上述内容的典型 Java 程序员将理解原始代码试图做什么。

然而,反编译器有几个非目标

  1. 重现原始源代码不是目标。 (这在数学上是不可能的!)

  2. 生成风格上“最佳实践”的代码并不是目标。 由于多种原因,这是不切实际的。 (首先,人们无法就什么是最佳实践达成一致!)

  3. In 不是生成始终可编译的代码的目标。 对于没有被混淆的字节码来说可能是可能的,但是:

    • 很难涵盖边缘情况,
    • 不可能证明你已经涵盖了所有的边缘情况
    • 您需要支持的编译器集一直在增长。

这在实践中意味着什么?

实际上,由反编译器生成的代码通常是1可读的,并且可能是可编译的,但是:

  • 您可能需要更正编译错误
  • 代码不像原始源代码那样可维护2
  • 该代码不适合用作如何编程的示例。

1 - 但是,如果字节码已被混淆,则所有赌注都将关闭。 混淆的目的是使反编译代码和/或理解反编译代码变得困难

2 - 首先,当您编译代码时,编译器会丢弃所有源代码注释和(通常)局部变量的名称。 然后它将各种结构(例如增强循环、内部类和 lambda 表达式)转换为 JVM 支持的更简单的形式。 这些转变是不可逆的。

一个简单的(但可能不是最好的)解决方案是将内部迭代器称为ir其他东西。

前任。 更改这一行: Iterator i$ = ((List)pendingFilesPerCheckpoint.get(pastCheckpointId)).iterator();

像这样: Iterator ir = ((List)pendingFilesPerCheckpoint.get(pastCheckpointId)).iterator();

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM