提问人:questionto42 提问时间:7/12/2020 最后编辑:questionto42 更新时间:4/22/2021 访问量:273
vscode: in “while ((inputLine = in.readLine()) != null)”-loop.x = x + a 没有警告。Versus: x += “未使用局部变量的值”
vscode: in "while ((inputLine = in.readLine()) != null)"-loop. x = x + a without warning. Versus: x += a "value of the local variable is not used"
问:
以下是 https://docs.oracle.com/javase/tutorial/networking/urls/readingURL.html 中的一个示例,唯一的变化是将 String inputLine 的内容添加到 strAll String 中,而不是打印它,请参阅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,警告出现在“问题”窗口中。
答:
下面是一个更简单、孤立的相同效果的实例。
这两种变体都编译为相同的字节码。
在此示例中,
a += 1;
IDE 看到 1 更新,但没有看到 的直接用法。a
a
在此示例中,
a = a + 1;
IDE 看到在表达式中使用,然后分配回 ,因此从 IDE 的角度来看,已被使用。a
a + 1
a
a
仅仅为变量赋值并不构成使用。
请注意,此行为也存在于 中,但如果需要,可以禁用。unused
Eclipse IDE
评论
此警告不是 Java 语言的一部分,甚至不是 Java 编译器的一部分。这只是 Visual Studio Code 试图提供帮助。
这是 vs code 中静态代码分析功能中的一个 bug 或限制。它算作变量的“使用”,而不算作变量的“使用”。如果代码分析更智能,它将在这两种情况下都给出“未使用的变量”警告。strAll = strAll + inputLine
strAll
strAll += inputLine
评论
为了完整起见,这是我对 github 问题的回答:
strAll += inputLine
是“复合赋值表达式”。因为这是 Java 的内置结构,所以 ecj(用于 vscode 的 Eclipse 编译器)知道这个结构的细节,特别是它跟踪隐式读取不会创建从另一个变量或参数到另一个变量或参数的数据流。strAll
strAll = strAll + inputLine
然而,这只是无数形式中的一种,人类读者很容易看到它真的无处流动。strAll
虽然区别对待这两种形式的决定是在我加入 Eclipse 之前做出的,但我很确定团队认为这是 ecj 可以推理的事情和过于复杂的事情之间最清晰的界限。扩展流量分析时需要讨论的内容的一些示例:
strAll = "foo" + strAll + "bar";
strAll = (bar = strAll) + "foo";
strAll = convert(strAll);
这个比第一眼看起来更棘手- 等等。
所以模式可能是 ecj 给你一根手指,人们会拿走整个手臂,或者更多......
底线:如果您想向 Java 编译器提供更多信息,请适当地使用 Java 细节:)复合赋值比其长形式传达的信息更多。
关于,我认为(无需仔细观察),当发现方法无法正常完成时,流分析就会停止。while (true)
评论