How can I make a method take a null value?

痴心易碎 提交于 2019-12-12 06:04:33

问题


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.

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)?

Something like this:

public void methodName(null null){}

How can I make a method which must take a null?


回答1:


As you've seen, the compiler can't resolve two methods that take different kinds of objects when you pass 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:

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.




回答2:


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". 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 (i.e. both method calls below would call the same overloaded method),

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.




回答3:


There is a type which is often used to represent a null and this is Void where the only valid value is 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;, however Runnable cannot throw a checked exception, so we much use Callable if we expect to capture the IOException in the future object.

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

Future<Void> future = executorService.submit(() -> {
        try(FileInputStream fis = new FileInputStream(filename)) {
            doSomething(fis);
        }
        return null;
    });



回答4:


An argument passed can always always be null if it is an Object. It is when you try running a method on a null reference that you get a null pointer exception.

So, public void methodName(File file){} could be called as methodName(null) without an exception.

However,

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

will result in a null pointer exception if null is passed.




回答5:


You can't write a method that specifically takes 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. If you have it call another method and methodName(File) and someOtherMethod() are not both final, you should document the internal call.




回答6:


You cannot do this. Remember that you may have implicit 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.

On the other hand why stick to 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


来源:https://stackoverflow.com/questions/32063904/how-can-i-make-a-method-take-a-null-value

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!