简体   繁体   English

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

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

Can someone please help identify what is the issue with the below code... and why is there a problem in compiling for the variable "i$"有人可以帮助确定以下代码的问题......以及为什么在编译变量“i$”时出现问题

Below is the code....下面是代码......

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);
                }
            }
        }

    }

Even though the i$ is defined inside curly braces second time... it says, the variable i$ is already defined in the scope....即使i$是第二次在大括号内定义的……它说,变量i$已经在作用域中定义了……

Can someone please help me fix this... and understand what is wrong with the variable i$ in the above code.有人可以帮我解决这个问题吗……并了解上面代码中的变量 i$ 有什么问题。

Thanks a lot.非常感谢。

The scope of a variable is the (entire) block in which it's defined, which of course includes all sub-blocks within the declaring block.变量的范围是定义它的(整个)块,当然包括声明块中的所有子块。

To fix the problem, use different variable names.要解决此问题,请使用不同的变量名称。

You commented this:你评论了这个:

but wondering, why this is creating problem... as i copied this method from other class and that is working fine... but mine is creating problem.... can you please explain但想知道,为什么这会产生问题......因为我从其他类复制了这个方法并且工作正常......但我的正在产生问题......你能解释一下吗

OK what you actually did is that you decompiled a class and copied the decompiled code into your source code.好的,您实际上所做的是反编译一个类并将反编译的代码复制到您的源代码中。

That approach often doesn't work.这种方法往往行不通。 And yours is an example where it hasn't worked.而你的就是一个没有奏效的例子。

The design goals for a typical Java decompiler is to translate compiled code into something that a programmer can read .典型 Java 反编译器的设计目标是将编译后的代码翻译成程序员可以阅读的内容 The decompiled code above satisfies this.上面的反编译代码满足了这一点。 A typical Java programmer reading the above will understand what the original code was trying to do.阅读上述内容的典型 Java 程序员将理解原始代码试图做什么。

However there are a couple of non-goals for a decompiler:然而,反编译器有几个非目标

  1. It is NOT a goal to reproduce the original source code.重现原始源代码不是目标。 (It is mathematically impossible to do that!) (这在数学上是不可能的!)

  2. It is NOT a goal to produce code that is "best practice" in style.生成风格上“最佳实践”的代码并不是目标。 That is impractical for a number of reasons.由于多种原因,这是不切实际的。 (For a start, people can't agree on what best practice is!) (首先,人们无法就什么是最佳实践达成一致!)

  3. In is NOT a goal to produce code that is always compilable. In 不是生成始终可编译的代码的目标。 It might be possible for bytecodes that haven't been obfuscated, but:对于没有被混淆的字节码来说可能是可能的,但是:

    • it is really hard to cover the edge cases,很难涵盖边缘情况,
    • it is impossible to prove that you have covered all of the edge cases不可能证明你已经涵盖了所有的边缘情况
    • and the set of compilers whose code you need to support is growing all of the time.您需要支持的编译器集一直在增长。

What does this mean in practice?这在实践中意味着什么?

In practice code that is generated by a decompiler is generally 1 readable, and may be compilable, but:实际上,由反编译器生成的代码通常是1可读的,并且可能是可编译的,但是:

  • you may need to correct compilation errors您可能需要更正编译错误
  • the code is not as maintainable as the original source code 2代码不像原始源代码那样可维护2
  • the code is not suitable for use as an example of how to program.该代码不适合用作如何编程的示例。

1 - However, if the bytecodes have been obfuscated, all bets are off. 1 - 但是,如果字节码已被混淆,则所有赌注都将关闭。 The purpose of obfuscation is to make it difficult to decompile code and / or understand the decompiled code.混淆的目的是使反编译代码和/或理解反编译代码变得困难

2 - For a start, when you compile code, the compiler discards all source code comments and (typically) the names of local variables. 2 - 首先,当您编译代码时,编译器会丢弃所有源代码注释和(通常)局部变量的名称。 Then it transforms various constructs such as enhanced loops, inner classes and lambdas into simpler forms that the JVM supports.然后它将各种结构(例如增强循环、内部类和 lambda 表达式)转换为 JVM 支持的更简单的形式。 These transformations are not reversible.这些转变是不可逆的。

A simple (but possibly not the best) solution is to just call the inner iterator something else like ir or something.一个简单的(但可能不是最好的)解决方案是将内部迭代器称为ir其他东西。

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

to something like this: Iterator ir = ((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