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 “只要相信我,它就會被初始化”。
在您收到“潛在的空指針訪問”消息的變體中:
這是警告,不是錯誤。
您可以忽略或抑制警告。(如果您的正確性分析是錯誤的,那么您可能會得到 NPE。但這是您的選擇。)
您可以使用編譯器開關(guān)關(guān)閉部分或全部警告。
@SuppressWarnings
您可以使用注釋抑制特定警告:對于 Eclipse,使用
@SuppressWarnings("null")
.對于 Android,請使用
@SuppressWarnings("ConstantConditions")
.不幸的是,警告標(biāo)簽并未完全標(biāo)準(zhǔn)化。但是,編譯器應(yīng)該默默地忽略
@SuppressWarnings
它無法識別的警告標(biāo)記。您也許能夠重組代碼。
在您的示例中,代碼正在使用 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)行不同的檢查。)

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í)行代碼而沒有抱怨。

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*/);

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ù)需要向其中添加元素。
添加回答
舉報