繁体   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