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