[英]How can I make a method take a null value?
If you have two overloaded methods like so: 如果您有两个这样的重载方法:
public void methodName(File file){}
public void methodName(String string){}
If you try to call methodName
with null
you will get an error saying that it's ambiguous which is understandable because it doesn't know which method to do. 如果尝试使用
null
调用methodName
,则会收到一条错误消息,指出它模棱两可,这是可以理解的,因为它不知道该使用哪种方法。
I know that you can just cast the null: methodName((String) null)
but how can I create a method specifically to handle the situations where you call methodName(null)
? 我知道您可以
methodName((String) null)
为null: methodName((String) null)
但是如何创建专门用于处理调用methodName(null)
的情况的方法?
Something like this: 像这样:
public void methodName(null null){}
How can I make a method which must take a null? 如何制作必须为null的方法?
Just make a method without any parameters. 只需创建一个没有任何参数的方法即可。
public void methodName(){}
Requiring a method that must take a null
is the same as requiring a method that always takes 5 or a method that always takes "foo". 要求
must take a null
的方法与要求始终为5的方法或始终为“ foo”的方法相同。 If the passed argument should always contain the same value, there's no need for that argument at all. 如果传递的参数应始终包含相同的值,则根本不需要该参数。
And if you were asking for a method that will be chosen whenever the passed argument is null, regardless of its type (ie both method calls below would call the same overloaded method), 而且,如果您要求的是在传递的参数为null时无论其类型如何都将选择的方法(即,下面的两个方法调用都将调用相同的重载方法),
File f = null;
String s = null;
methodName (f);
methodName (s);
that's not possible, since the overloaded method to be used must be chosen in compile time using the compile time types of the arguments. 这是不可能的,因为必须在编译时使用参数的编译时类型选择要使用的重载方法。 At compile time the compiler can't know that the passed variable with contain null when the method is executed.
在执行该方法时,编译器在编译时无法知道所传递的变量是否包含null。
There is a type which is often used to represent a null
and this is Void
where the only valid value is null
. 有一种类型通常用于表示
null
,这是Void
,其中唯一有效的值是null
。
You can write 你可以写
void methodName(Void v);
Where it is typically used is for generic return types like. 通常将其用于通用返回类型,例如。
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();
You might wonder, why not use Runnable
as we would not need return null;
您可能想知道,为什么不使用
Runnable
因为我们不需要return null;
, however Runnable
cannot throw a checked exception, so we much use Callable if we expect to capture the IOException in the future
object. ,但是
Runnable
不能引发已检查的异常,因此如果我们希望在future
对象中捕获IOException,则可以大量使用Callable。
In Java 8, you can use lambdas but the compiler will still expect to return a null if you throw a checked exception as it works out you have to be using Callable 在Java 8中,您可以使用lambdas,但如果抛出已检查的异常,编译器仍然希望返回null,因为它必须使用Callable
Future<Void> future = executorService.submit(() -> {
try(FileInputStream fis = new FileInputStream(filename)) {
doSomething(fis);
}
return null;
});
An argument passed can always always be null if it is an Object
. 如果传递的参数是
Object
,则始终可以始终为null。 It is when you try running a method on a null reference that you get a null pointer exception. 当您尝试在null引用上运行方法时,会得到null指针异常。
So, public void methodName(File file){}
could be called as methodName(null)
without an exception. 因此,
public void methodName(File file){}
可以毫无例外地称为methodName(null)
。
However, 然而,
public void methodName(File file) {
file.delete();
}
will result in a null pointer exception if null is passed. 如果传递null,将导致null指针异常。
You can't write a method that specifically takes null
. 您不能编写专门采用
null
的方法。 You'd have to do something like this: 您必须执行以下操作:
methodName(File file) {
if(file == null) {
someOtherMethod();
}
else {
// other stuff
}
}
But it would be more common to just have methodName(File)
handle null
, and document what it does with null
. 但是,仅使
methodName(File)
处理null
并记录其对null
所做的操作会更常见。 If you have it call another method and methodName(File)
and someOtherMethod()
are not both final, you should document the internal call. 如果您有调用另一个方法,而
methodName(File)
和someOtherMethod()
都不都是最终的,则应记录内部调用。
You cannot do this. 你不可以做这个。 Remember that you may have implicit
null
. 请记住,您可能具有隐式
null
。 For example: 例如:
File file = null;
methodName(file);
However, Java compiler must link the call to the specific method signature, so it should know in compile time whether the null
was passed. 但是,Java编译器必须将调用链接到特定的方法签名,因此它应该在编译时知道是否传递了
null
。
On the other hand why stick to null
? 另一方面,为什么要坚持为
null
? Nothing stops you to define the special type: 没有什么可以阻止您定义特殊类型的:
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
As you've seen, the compiler can't resolve two methods that take different kinds of objects when you pass null
. 如您所见,当传递
null
时,编译器无法解析采用不同类型对象的两个方法。
The only way around this is either typecast, like you have done, or to have a method that takes a generic Object
type and attempts to downcast: 解决此问题的唯一方法是像您一样进行类型转换,或者采用一种采用通用
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
}
}
Writing code that looks like this tends to be viewed as smelly, and for good reason. 编写看起来像这样的代码通常被认为是臭的,这是有充分理由的。 It gets complicated quickly, is difficult to maintain, etc. Your best bet is to typecast or to change your method signatures so that you (and the compiler) always know which function should be called to handle a specific
null
object. 它很快就会变得复杂,难以维护等。您最好的选择是进行类型转换或更改方法签名,以便您(和编译器)始终知道应调用哪个函数来处理特定的
null
对象。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.