简体   繁体   中英

avoiding “Potential null pointer access”

which would you say is the best practice when implementing the following problem:

MyClass myVariable = null;
if ( ..condition 1.. ) {
  myVariable = new MyClass(1);
} else if ( ..condition 2.. ) {
  myVariable = new MyClass(2);
}

myVariable.execute();

Which would be a good solution to the warning?

  1. A finishing else

     final MyClass myVariable; .... } else { // let's say this assert makes sense here Assert.fail("This should not happen"); } 
  2. throw RuntimeException

     final MyClass myVariable; .... } else { throw new RuntimeException("Some message, like <should not happen>"); } 
  3. Check for NPE

     final MyClass myVariable; .... if (myVariable != null) { myVariable.execute(); } 
  4. Other ideas?

Thanks in advance!

It depends on whether either condition 1 or condition 2 must always be true. If condition 2 is the exact opposite of condition 1, you can replace the else if ( ..condition 2.. ) with else and solve your problem.

If it's not, and the fact that both condition 1 and condition 2 are false indicates some invalid input, I'd throw an exception.

If the scenario in which both conditions are false is a valid scenario, I'd check that myVariable is not null before calling myVariable.execute() .

Better is the following.

final param;
if ( ..condition 1.. ) {
  param = 1;
} else if ( ..condition 2.. ) {
  param = 2;
} else {
   throw new IllegalArgumentException("no condition matches");
}

new MyClass(param).execute();

If your conditions are simple try to re-write if-else chain using switch-case. It is better.

I would do a null-check, like your 3rd example. If the feature you are implementing is a side-feature or something optional, you can probably ignore it when your variable is null. When you have a main feature 'though, and the user awaits response, you should then message the user and ask him to try again.

If you can always initialise your variable, use an if-else which ends with an else :

MyClass myClass;

if (...)
    myClass = new MyClass(1);
else if (...)
    myClass = new MyClass(2);
else if (...)
    ...
else
    myClass = new MyClass(n);

myClass.execute();

If you can't always initialise your variable and you want to use the variable only when initialised:

MyClass myClass;

if (...)
    myClass = new MyClass(1);
else if (...)
    myClass = new MyClass(2);
else if (...)
    ...

if (myClass != null)
    myClass.execute();

If you can't always initialise your variable but it is needed:

MyClass myClass;

if (...)
    myClass = new MyClass(1);
else if (...)
    myClass = new MyClass(2);
else if (...)
    ...
else
    throw new Exception(...);// or notify the user and exit

myClass.execute();

Another approach is to define an init() method:

MyClass myClass = init(...);

// check if myClass is != null if init can return a null
myClass.execute();

MyClass init(...) {
    if (...)
        return new MyClass(1);
    else if (...)
        return new MyClass(2);
    else if (...)
        ...
    else
        return new MyClass(n);// or return null

In short, it depends on the case you are.

which would you say is the best practice when implementing the following problem

It depends on the context:

  • It depends on the (deep) purpose of checking condition 1 and condition 2 .

  • It depends on what it means for them to both be false:

    • Is it a "normal" condition?

    • Is it a user input error?

    • Is it a programming error in the code that called this method?

    • Is it a programming error in this code; eg a violation of an invariant?

    • Something else?

  • It depends on how you want that case to be treated.

Depending on that, any of your proposed alternatives could be appropriate.


... which would you say is the best practice ...

I would not use the phrase "best practice" for something like this. Not even if I knew the context. Whenever I hear the phrase "best practice" in a question, I get the impression that someone wants a "cookie cutter" solution that they can apply without thinking.

The only "best practice" I would recommend here is to understand the context, and pick the solution most appropriate to it.

And ... "any solution that makes the warning go away" is NOT the right approach.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM