Java中如何避免空指標異常
這個問題對於我來說是一個很常見的問題,這也是由初級程式設計師成長到中級程式設計師的時候經常會遇到的問題。程式設計師不知道或不信任正在使用的約定,並且小心的檢查著null。還有當程式設計師寫程式碼的時候,總是會依賴於通過返回空(NULL)來表明某些意義,因此需要呼叫者去檢查Null。換種方式來說,有兩種空指標的檢查場景:
-
期望的結果就是null。
-
期望的結果不是null。
第二種很簡單,可以通過用assert或者允許程式報錯,例如丟擲NullPointerException。Assertions是一個從Java1.4加進來的高度未被利用的特性,語法是:
assert <condition>
或者
assert <condition> : <object>
condition是一個布林表示式,object是一個物件(其toString()方法的輸出將會被包含在錯誤裡)。
校對注:我測試了下,JDK1.4及其以上,執行前設定vm引數-ea
public
static
void
main
(
String
[
] args
)
{
String name
=
null
;
assert
(name
!=
null
)
:
"name為空null"
;
}
Exception
in thread
"main"
; java
.lang
.AssertionError
: 變數name為空
null
at LogUtil
.
main
(LogUtil
.java
:
37
)
如果condition為false的話,assert將會丟擲一個Error(AssertionError)。預設Java會忽略斷言你可以通過在JVM中傳入一個-ea引數來啟用斷言。
你可以為單獨的一個包或者類啟動關閉assertions。這意味著你可以在開發和測試的時候通過斷言來驗證程式碼,在釋出產品的時候關閉它,儘管我下面展示的測試中並沒有因為assertions而損失效能。在這個程式碼段中不用斷言也可以,因為他會執行失敗的,就像加了斷言一樣。唯一的區別是有了斷言可能會發生的更快一些,更有意義,並且會附加一些額外的資訊,而這可以幫助你弄明白失敗的原因。
第一種有一點棘手。如果你對不能控制正在呼叫的這段程式碼,那你就卡住了。如果Null是一個合理的返回值,你就應該檢查它。如果是你能夠控制的程式碼,那就是個完全不同的故事情景了。儘量避免用NULL作為返回值。對於返回Collections的集合很容易,返回Empty(一個空集合或者陣列),而不是一直用null作為返回值。對於不是返回Collections的方法會有一點複雜。考慮下面這個例子:
public
interface
Action
{
void
doSomething
(
)
;
}
public
interface
Parser
{
Action
findAction
(String userInput
)
;
}
Parser採用使用者的輸入作為引數,然後做一些事情(例如模擬一個命令列)。現在你可能會
返回null,如果沒找到對應輸入的動作的話,這就導致了剛才說過的空指標檢查。
一個可選的解決方案是永遠不要返回null,而是返回一個空物件,
//java學習交流:737251827 進入可領取學習資源及對十年開發經驗大佬提問,免費解答!
public
class
MyParser
implements
Parser
{
private
static Action
DO_NOTHING
=
new
Action
(
)
{
public
void
doSomething
(
)
{
/* do nothing */
}
}
;
public Action
findAction
(
String userInput
)
{
// ...
if
(
/* we can't find any actions */
)
{
return
DO_NOTHING
;
}
}
比較這段程式碼:
Parser parser
= ParserFactory
.
getParser
(
)
;
if
(parser
==
null
)
{
// now what?
// this would be an example of where null isn't (or shouldn't be) a valid response
}
Action action
= parser
.
findAction
(someInput
)
;
if
(action
==
null
)
{
// do nothing
}
else
{
action
.
doSomething
(
)
;
}
和這段:
ParserFactory.getParser().findAction(someInput).doSomething();
這是個更好的設計,因為足夠簡潔,避免了多餘的判斷。即便如此,或許比較合適的設計是:findAction()方法之惡傑丟擲一個異常,其中包含一些有意義的錯誤資訊—–特別是在這個案例中你依賴於使用者的輸入。讓findAction()方法丟擲一個異常而不是簡單的產生一個沒有任何解釋的NullPointerException 要好得多。
try
{
ParserFactory
.
getParser
(
)
.
findAction
(someInput
)
.
doSomething
(
)
;
}
catch
(ActionNotFoundException anfe
)
{
userConsole
.
err
(anfe
.
getMessage
(
)
)
;
}
或者你認為try/catch 的機制太醜了,你的action應該跟使用者提供一個反饋而不是什麼都不做:
public Action
findAction
(
final String userInput
)
{
/* Code to return requested Action if found */
return
new
Action
(
)
{
public
void
doSomething
(
)
{
userConsole
.
err
(
"Action not found: "
+ userInput
)
;
}
}
}
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70010294/viewspace-2843899/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- [轉載] java避免空指標異常_第1部分:在現代Java應用程式中避免空指標異常Java指標
- Java中如何處理空指標異常Java指標
- Java中的空指標異常 java.lang.NullPointerExceptionJava指標NullException
- java.lang.NullPointerException 空指標異常問題JavaNullException指標
- 如何在 Java8 中風騷走位避開空指標異常Java指標
- 如何避免空指標出錯?指標
- 如何避免Java程式碼中的空指標錯誤NullPointerException? - foojayJava指標NullException
- NullPointerException空指標異常的理解NullException指標
- 聊一聊日常開發中如何優雅的避免那無處不在的空指標異常指標
- Kafka SimpleStringSchema 可能會造成空指標異常Kafka指標
- Java8新特性之空指標異常的剋星Optional類Java指標
- Spring中new出一個物件導致的空指標異常Spring物件指標
- 我在大廠做 CR——如何體系化防控空指標異常指標
- 【優雅程式碼】03-optional杜絕空指標異常指標
- springboot+mybatis,mapper呼叫查詢的資料為空,報空指標異常Spring BootMyBatisAPP指標
- 關於Paging + Room,RecyclerView重新整理時的空指標異常OOMView指標
- Java8的Optional:如何幹掉空指標?Java指標
- 如何善用Java異常Java
- java中的異常Java
- Java 中的異常Java
- 翻譯 | Java流中如何處理異常Java
- 防止空指標指標
- Java關於空指標的防範與思考Java指標
- 【java】異常Java
- java 異常Java
- Java 異常Java
- Java異常Java
- 異常JavaJava
- Java 異常(二) 自定義異常Java
- 【Java8新特性】Optional類在處理空值判斷場景的應用 迴避空指標異常 編寫健壯的應用程式Java指標
- GO 空指標和nilGo指標
- 空指標的傳說指標
- python中如何捕獲異常Python
- Java 14版本中將加入發現空指標錯誤提示功能Java指標
- 如何優雅的設計Java異常Java
- java空指標出現的情況:拆箱裝箱Java指標
- jmu-Java-06異常-01-常見異常Java
- Java 異常表與異常處理原理Java