簡體   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