[英]How can I make a method take a null value?
如果您有兩個這樣的重載方法:
public void methodName(File file){}
public void methodName(String string){}
如果嘗試使用null
調用methodName
,則會收到一條錯誤消息,指出它模棱兩可,這是可以理解的,因為它不知道該使用哪種方法。
我知道您可以methodName((String) null)
為null: methodName((String) null)
但是如何創建專門用於處理調用methodName(null)
的情況的方法?
像這樣:
public void methodName(null null){}
如何制作必須為null的方法?
只需創建一個沒有任何參數的方法即可。
public void methodName(){}
要求must take a null
的方法與要求始終為5的方法或始終為“ foo”的方法相同。 如果傳遞的參數應始終包含相同的值,則根本不需要該參數。
而且,如果您要求的是在傳遞的參數為null時無論其類型如何都將選擇的方法(即,下面的兩個方法調用都將調用相同的重載方法),
File f = null;
String s = null;
methodName (f);
methodName (s);
這是不可能的,因為必須在編譯時使用參數的編譯時類型選擇要使用的重載方法。 在執行該方法時,編譯器在編譯時無法知道所傳遞的變量是否包含null。
有一種類型通常用於表示null
,這是Void
,其中唯一有效的值是null
。
你可以寫
void methodName(Void v);
通常將其用於通用返回類型,例如。
Future<Void> future = executorService.submit(new Callable<Void>() {
public Void call() throws IOException {
try(FileInputStream fis = new FileInputStream(filename)) {
doSomething(fis);
}
return null;
}
});
// later
future.get();
您可能想知道,為什么不使用Runnable
因為我們不需要return null;
,但是Runnable
不能引發已檢查的異常,因此如果我們希望在future
對象中捕獲IOException,則可以大量使用Callable。
在Java 8中,您可以使用lambdas,但如果拋出已檢查的異常,編譯器仍然希望返回null,因為它必須使用Callable
Future<Void> future = executorService.submit(() -> {
try(FileInputStream fis = new FileInputStream(filename)) {
doSomething(fis);
}
return null;
});
如果傳遞的參數是Object
,則始終可以始終為null。 當您嘗試在null引用上運行方法時,會得到null指針異常。
因此, public void methodName(File file){}
可以毫無例外地稱為methodName(null)
。
然而,
public void methodName(File file) {
file.delete();
}
如果傳遞null,將導致null指針異常。
您不能編寫專門采用null
的方法。 您必須執行以下操作:
methodName(File file) {
if(file == null) {
someOtherMethod();
}
else {
// other stuff
}
}
但是,僅使methodName(File)
處理null
並記錄其對null
所做的操作會更常見。 如果您有調用另一個方法,而methodName(File)
和someOtherMethod()
都不都是最終的,則應記錄內部調用。
你不可以做這個。 請記住,您可能具有隱式null
。 例如:
File file = null;
methodName(file);
但是,Java編譯器必須將調用鏈接到特定的方法簽名,因此它應該在編譯時知道是否傳遞了null
。
另一方面,為什么要堅持為null
? 沒有什么可以阻止您定義特殊類型的:
enum Null { NULL }
public void methodName(File file){}
public void methodName(String string){}
public void methodName(Null n) {}
methodName(Null.NULL); // or methodName(NULL); with import static
如您所見,當傳遞null
時,編譯器無法解析采用不同類型對象的兩個方法。
解決此問題的唯一方法是像您一樣進行類型轉換,或者采用一種采用通用Object
類型並嘗試向下轉換的方法:
public void methodName( Object object ) {
if ( object == null ) {
// do something with null
} else if ( object instanceof File ) {
// do something with ((File)object)
} else {
// do something else
}
}
編寫看起來像這樣的代碼通常被認為是臭的,這是有充分理由的。 它很快就會變得復雜,難以維護等。您最好的選擇是進行類型轉換或更改方法簽名,以便您(和編譯器)始終知道應調用哪個函數來處理特定的null
對象。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.