Java 如何使方法接受空值?

Java 如何使方法接受空值?,java,null,method-signature,Java,Null,Method Signature,如果有两个重载方法,如下所示: public void methodName(File file){} public void methodName(String string){} 如果您尝试使用null调用methodName,您将得到一个错误,表明它不明确,这是可以理解的,因为它不知道该使用哪个方法 我知道您可以强制转换null:methodName((String)null),但是我如何创建一个方法来专门处理调用methodName(null)的情况呢 大概是这样的: public v

如果有两个重载方法,如下所示:

public void methodName(File file){}
public void methodName(String string){}
如果您尝试使用
null
调用
methodName
,您将得到一个错误,表明它不明确,这是可以理解的,因为它不知道该使用哪个方法

我知道您可以强制转换null:
methodName((String)null)
,但是我如何创建一个方法来专门处理调用
methodName(null)
的情况呢

大概是这样的:

public void methodName(null null){}
methodName(File file) {
   if(file == null) {
      someOtherMethod();
   }
   else {
      // other stuff
   }
}

如何创建一个必须为null的方法?

只需创建一个没有任何参数的方法即可

public void methodName(){}
要求
必须取null的方法与要求总是取5的方法或总是取“foo”的方法相同。如果传递的参数应始终包含相同的值,则根本不需要该参数

如果您要求在传递的参数为null时选择一个方法,而不管其类型如何(即下面的两个方法调用将调用相同的重载方法)


这是不可能的,因为要使用的重载方法必须在编译时使用参数的编译时类型进行选择。在编译时,编译器在执行方法时无法知道传递的变量是否包含null

只需创建一个没有任何参数的方法即可

public void methodName(){}
要求
必须取null的方法与要求总是取5的方法或总是取“foo”的方法相同。如果传递的参数应始终包含相同的值,则根本不需要该参数

如果您要求在传递的参数为null时选择一个方法,而不管其类型如何(即下面的两个方法调用将调用相同的重载方法)

这是不可能的,因为要使用的重载方法必须在编译时使用参数的编译时类型进行选择。在编译时,编译器在执行方法时无法知道传递的变量是否包含null

如果传递的参数是
对象
,则该参数始终可以为空。当您尝试在null引用上运行方法时,您会得到null指针异常

因此,
public-void-methodName(File-File){}
可以毫无例外地被称为
methodName(null)

但是,

public void methodName(File file) {
    file.delete();
}
如果传递null,将导致null指针异常。

如果传递的参数是
对象,则它始终可以是null。当您尝试在null引用上运行方法时,您会得到null指针异常

因此,
public-void-methodName(File-File){}
可以毫无例外地被称为
methodName(null)

但是,

public void methodName(File file) {
    file.delete();
}

如果传递null,将导致null指针异常。

如您所见,当传递null时,编译器无法解析接受不同类型对象的两个方法

解决此问题的唯一方法是像您所做的那样进行类型转换,或者使用一个接受泛型
对象
类型并尝试向下转换的方法:

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
对象。

如您所见,当您传递
null
时,编译器无法解析接受不同类型对象的两个方法

解决此问题的唯一方法是像您所做的那样进行类型转换,或者使用一个接受泛型
对象
类型并尝试向下转换的方法:

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
对象。

您不能编写专门接受
null
的方法。你必须这样做:

public void methodName(null null){}
methodName(File file) {
   if(file == null) {
      someOtherMethod();
   }
   else {
      // other stuff
   }
}

但更常见的情况是只使用
methodName(File)
handle
null
,并记录它对
null
的操作。如果您让它调用另一个方法,并且
methodName(File)
someOtherMethod()
都不是最终的,那么您应该记录内部调用。

您不能编写专门接受
null
的方法。你必须这样做:

public void methodName(null null){}
methodName(File file) {
   if(file == null) {
      someOtherMethod();
   }
   else {
      // other stuff
   }
}

但更常见的情况是只使用
methodName(File)
handle
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
。例如:

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
,它是
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();

有一种类型经常用来表示r