簡體   English   中英

如何使方法采用空值?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM