第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何告訴 Java 一個變量不可能為空?

如何告訴 Java 一個變量不可能為空?

慕尼黑5688855 2022-11-30 13:21:47
我有一個基本上看起來像這樣的程序:boolean[] stuffNThings;int state=1;for(String string:list){   switch(state){      case 1:         if(/*condition*/){            // foo            break;         }else{            stuffNThings=new boolean[/*size*/];            state=2;         }      // intentional fallthrough      case 2:         // bar         stuffNThings[0]=true;   }}正如你,一個人,可以看到,情況 2 只會發(fā)生在以前有狀態(tài) 1 并且它在初始化數(shù)組后切換到狀態(tài) 2 時。但是 Eclipse 和 Java 編譯器看不到這一點,因為它們看起來像是非常復(fù)雜的邏輯。所以 Eclipse 抱怨:局部變量 stuffNThings 可能尚未初始化?!比绻覍ⅰ?boolean[] stuffNThings;”更改為“ boolean[] stuffNThings=null;”,它會切換到此錯誤消息:潛在的空指針訪問:變量 stuffNThings 在此位置可能為空。我也無法在頂部初始化它,因為數(shù)組的大小僅在狀態(tài) 1 的最終循環(huán)之后確定。Java 認(rèn)為那里的數(shù)組可能為空,但我知道它不能。有什么方法可以告訴 Java 嗎?還是我肯定被迫對其進(jìn)行無用的null檢查?添加它會使代碼更難理解,因為看起來可能存在值實際上并未設(shè)置為true.
查看完整描述

4 回答

?
小唯快跑啊

TA貢獻(xiàn)1863條經(jīng)驗 獲得超2個贊

Java 認(rèn)為那里的數(shù)組可能為空,但我知道它不能。

嚴(yán)格來說,Java 認(rèn)為變量可以是未初始化的。如果未明確初始化,則該值不應(yīng)該是可觀察的。

(變量是靜默初始化null還是處于不確定狀態(tài)是一個實現(xiàn)細(xì)節(jié)。關(guān)鍵是,語言說你不應(yīng)該被允許看到這個值。)

但無論如何,解決方案是將其初始化為null. 它是多余的,但是沒有辦法告訴 Java “只要相信我,它就會被初始化”。


在您收到“潛在的空指針訪問”消息的變體中:

  1. 這是警告,不是錯誤。

  2. 您可以忽略或抑制警告。(如果您的正確性分析是錯誤的,那么您可能會得到 NPE。但這是您的選擇。)

  3. 您可以使用編譯器開關(guān)關(guān)閉部分或全部警告。

  4. @SuppressWarnings您可以使用注釋抑制特定警告:

    • 對于 Eclipse,使用@SuppressWarnings("null").

    • 對于 Android,請使用@SuppressWarnings("ConstantConditions").

      不幸的是,警告標(biāo)簽并未完全標(biāo)準(zhǔn)化。但是,編譯器應(yīng)該默默地忽略@SuppressWarnings它無法識別的警告標(biāo)記。

  5. 您也許能夠重組代碼。

在您的示例中,代碼正在使用 switch drop through。人們很少這樣做,因為這會導(dǎo)致代碼難以理解。因此,我并不感到驚訝,您可以找到涉及 drop-through 的邊緣案例示例,在這種情況下,編譯器會收到一些錯誤的 NPE 警告。

無論哪種方式,您都可以通過重構(gòu)代碼輕松地避免進(jìn)行 drop-through 的需要。將案例中的代碼復(fù)制到case 2:案例末尾case 1:。固定的。繼續(xù)前行。


請注意,“可能未初始化”錯誤并不是 Java 編譯器“愚蠢”。JLS 有一整章關(guān)于明確分配的規(guī)則,等等。不允許 Java 編譯器對此很聰明,因為這意味著相同的 Java 代碼將合法或不合法,具體取決于編譯器的實現(xiàn)。這對代碼的可移植性不利。

我們這里實際擁有的是一種語言設(shè)計折衷方案。該語言阻止您使用(實際上)未初始化的變量。但是要做到這一點,“愚蠢”的編譯器有時必須阻止您使用您(聰明的程序員)知道將被初始化的變量……因為規(guī)則說它應(yīng)該。

(替代方案更糟糕:要么不對未初始化的變量進(jìn)行編譯時檢查,導(dǎo)致在不可預(yù)測的地方發(fā)生硬崩潰,要么對不同的編譯器進(jìn)行不同的檢查。)


查看完整回答
反對 回復(fù) 2022-11-30
?
繁星coding

TA貢獻(xiàn)1797條經(jīng)驗 獲得超4個贊

在不顧 Eclipse 的抱怨而嘗試執(zhí)行代碼之后,我注意到它確實運行沒有問題。因此,盡管并不重要,但顯然這只是一個被設(shè)置為“錯誤”級別的警告。
有一個“配置問題嚴(yán)重性”按鈕,所以我將“潛在空指針訪問”的嚴(yán)重性設(shè)置為“警告”(并相應(yīng)地調(diào)整了其他一些級別)。現(xiàn)在 Eclipse 只是將其標(biāo)記為警告并執(zhí)行代碼而沒有抱怨。

查看完整回答
反對 回復(fù) 2022-11-30
?
料青山看我應(yīng)如是

TA貢獻(xiàn)1772條經(jīng)驗 獲得超8個贊

更容易理解的是:


    boolean[] stuffNThings;

    boolean initialized = false;

    for (String string: list) {

        if (!initialized) {

            if (!/*condition*/) {

                stuffNThings = new boolean[/*size*/];

                initailized = true;

            }

        }

        if (initialized) {

            // bar

            stuffNThings[0] = true;

        }

    }

兩個循環(huán),一個用于初始化,一個用于玩這些東西可能更清楚也可能不會更清楚。


流量分析更容易(與直通交換機相比)。


此外,也可能使用 a 而不是 a boolean[](BitSet因為它不是固定大小的數(shù)組)。


BitSet stuffNThings = new BitSet(/*max size*/);


查看完整回答
反對 回復(fù) 2022-11-30
?
夢里花落0921

TA貢獻(xiàn)1772條經(jīng)驗 獲得超6個贊

一個明顯的非答案:當(dāng)代碼“如此”復(fù)雜以至于 IDE / java 編譯器“看不到它”時,這很好地表明您的代碼無論如何都太復(fù)雜了。至少對我來說,你說的話并不明顯。我不得不反復(fù)上下閱讀以說服自己問題中給出的陳述是正確的。

您在 for 的開關(guān)中有一個 if。干凈的代碼和“單層抽象”會告訴您:這不是一個好的起點。

看看你的代碼。你所擁有的是一個偽裝的狀態(tài)機。問問自己是否值得在更大規(guī)模上重構(gòu)它,例如將它變成某種顯式狀態(tài)機。

另一個侵入性較小的想法:使用列表而不是數(shù)組。然后您可以簡單地創(chuàng)建一個空列表,并根據(jù)需要向其中添加元素。


查看完整回答
反對 回復(fù) 2022-11-30
  • 4 回答
  • 0 關(guān)注
  • 165 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學(xué)習(xí)伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號