繁体   English   中英

vscode:在“while ((inputLine = in.readLine()).= null)”-循环中。 x = x + a 没有警告:与:x += a “未使用局部变量的值”

[英]vscode: in “while ((inputLine = in.readLine()) != null)”-loop. x = x + a without warning. Versus: x += a “value of the local variable is not used”

The following is an example from https://docs.oracle.com/javase/tutorial/networking/urls/readingURL.html , the only change is that the content of the String inputLine is added up to the strAll String instead of printing it ,见 X_HERE。

import java.net.*;
import java.io.*;

public class URLReader {
    public static void main(String[] args) throws Exception {

        URL oracle = new URL("http://www.oracle.com/");
        BufferedReader in = new BufferedReader(
        new InputStreamReader(oracle.openStream()));

        String inputLine;
        String strAll = "";
        while ((inputLine = in.readLine()) != null)
            // System.out.println(inputLine);
            strAll = strAll + inputLine; // X_HERE
        in.close();
    }
}

这不会引发任何警告。 如果将行 X_HERE 替换为

strAll += inputLine;

使用“加法分配”你会得到警告:

未使用局部变量 strAll 的值

如果将 while 条件替换为 (true),strAll 的警告就会消失。 为什么在这种情况下对“加法赋值”有不同的处理?

感谢@Joni 编辑:我正在使用 Visual Studio Code,警告出现在“问题”Window 中。

这是相同效果的一个更简单、孤立的实例。

这两种变体都编译为相同的字节码。

在这个例子中,

a += 1;

IDE 看到a被更新了 1 但没有看到 a 的直接a

在这个例子中,

a = a + 1;

IDE 看到a在表达式a + 1中使用,然后分配回a ,因此从 IDE 的角度来看, a已被使用。

仅仅为变量赋值并不构成使用。

请注意,这种unused的行为也存在于Eclipse IDE中,但可以根据需要禁用。

此警告不是 Java 语言的一部分,甚至不是 Java 编译器的一部分。 这只是试图提供帮助的视觉工作室代码。

这是 vs 代码中 static 代码分析功能中的错误或限制。 它将strAll = strAll + inputLine为变量strAll的“使用”,而没有将等效的strAll += inputLine为变量的“使用”。 如果代码分析更智能,它将在这两种情况下为您提供“未使用的变量”警告。

为了完整起见,这是我对github 问题的回答:

strAll += inputLine是一个“复合赋值表达式”。 因为这是 Java 的内置结构,所以 ecj(用于 Java 的 Eclipse 编译器,在 vscode 中使用)知道这个结构的细节,特别是它跟踪隐式读取不会创建从strAll到的数据流另一个变量或参数。

strAll = strAll + inputLine只是无数 forms 中的一个,人类读者很容易看到strAll真的无处可去。

虽然在我任职 Eclipse 之前就已经做出了对 forms 进行不同处理的决定,但我很确定团队认为这是 ecj 可以推理的事情和过于复杂的事情之间最清晰的界限。 扩展流量分析时需要讨论的一些示例:

  • strAll = "foo" + strAll + "bar";
  • strAll = (bar = strAll) + "foo";
  • strAll = convert(strAll); // 这个比第一眼看起来更棘手
  • 等。

所以模式很可能是 ecj 给你一个手指,人们会拿走整个 arm,或者更多......

底线:如果您想为 Java 编译器提供更多信息,请适当使用 Java 详细信息:) 复合赋值比其长形式传达更多信息。

关于while (true) ,我认为(没有仔细观察),当发现方法无法正常完成时,流分析就会停止。

暂无
暂无

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

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