Check two denials in an if expression

Asked

Viewed 149 times

-3

I’m putting this on:

if(!teste.trim().equals("") || (!(teste == null))){
    // ...faz algo sem NullPointerException...
}

But the second clause is not working, the one that tests if it is not null.

I don’t know what I do.

Later I managed to do with two ifs:

if (sampleString != null){
    if(!sampleString.tri‌​m().equals("")){

But I wonder why the first way doesn’t work.

  • Before you said that I did. I did it with two ifs: if (sampleString != null){ if(! sampleString.Trim(). equals("")){

  • Renan because you deleted your comment?

  • Renan explains why this && and not ||? Because the variable can be null or Blank " "

  • because I need to check if first is null?

  • 1

    Why comments are disposable :D But responding: the way your code is, !teste.trim().equals("") would have already released an exception if "test" were null, so it makes no sense to check for null after checking that it is empty.

3 answers

5


Your problem is in interpreting the order in which the subexpressions are evaluated.

If you have an expression if (a || b), it will be evaluated so:

  • If a is true, then the whole expression will be true and the b will not be evaluated.
  • If a is true, so the b will be evaluated and the expression will be true if b is true or false if b is false.

In a similar way, an expression if (a && b) will be assessed as such:

  • If a is false, then the whole expression will be false and the b will not be evaluated.
  • If a is true, so the b will be evaluated and the expression will be true if b is true or false if b is false.

Note that in the case of ||, that the first sub-expression is true means that the second will not be evaluated, so any side effects that the second sub-expression could produce when being evaluated (including a NullPointerException) will not happen if the first subexpression is true. It also means that making a if (a || b) { can give a totally different effect to do if (b || a) {.

In your case, to avoid a NullPointerException, makes sense if you first check whether an object is or not null then try to use it (otherwise it makes no sense). And this is achieved by reversing the order of the subexpressions:

if((!(teste == null)) || !teste.trim().equals("")){
    // ...faz algo sem NullPointerException...
}

The reason is that if teste for null, then try to evaluate teste.trim() causes a NullPointerException, and that’s why the expression !(teste == null) has to be before the !teste.trim().

However, the code will still not work. There is still one more conceptual error, which can be easily revealed when trying to simplify it. First an expression !(a == b) is equivalent to a != b, and therefore (!(teste == null)) is the same as teste != null. So your expression would look like this:

if (teste != null || !teste.trim().equals("")) {
    // ...faz algo sem NullPointerException...
}

Knowing that the second subexpression will only be evaluated when the first is false, one wonders: In what circumstances is the first subexpression false? The answer is that it occurs when teste for null, and therefore the second sub-expression will only be evaluated when teste for null. However, if teste for null, then you will assuredly have a NullPointerException when assessing the second sub-expression!

What you really want is to get inside the if if teste is not null And nor empty. That is, it was to use the && instead of ||:

if (teste != null && !teste.trim().equals("")) {
    // ...faz algo sem NullPointerException...
}

Note that this is equivalent to the contour solution you found:

if (sampleString != null) {
    if (!sampleString.tri‌​m().equals("")) {
        // ...faz algo sem NullPointerException...
    }
}

For what these two ifs do is exactly the same as the && would: It will only enter when the two expressions are true and the second will only be evaluated if the first is true. In fact, a way of simplifying if (a) { if (b) { ... }} is exactly turn it into if (a && b) { ... }.

4

This is basic but can be tricky for those who are starting. Before invoking a method in any instance of the object always ask if it is null:

teste == null 
teste != null

If you try to invoke a method in a variable of any class type assigned with null will run into NullPointerException:

String teste = null;
teste.isEmpty();      //Vai dar NullPointerException

Then in your case it would be so:

if (!(teste == null) && !(teste.trim().equals("")) {
    // ...faz algo sem nullpointerException...
}

Or simpler:

if (teste != null && !teste.trim().isEmpty()) {
    // ...faz algo sem nullpointerException...
}

3

The error is in comparing the condition. Actually you have to first check whether the variable teste is null, then make any kind of check.

!(teste == null)

You have to do this way to check if the value is null:

teste != null

Explaining why the first way doesn’t work...

Let’s say the test isn’t null.

The first expression that is validated is within the parentheses, so teste == null returns false. What ! does is invert the result, so returns true.

What happens is that you were validating correctly and then getting the opposite result.

  • ? But that’s not exactly what I wanted... but thanks for trying to help me. :)

  • 2

    What did you want then? : 0

  • the fault was mine the question is half-asked. This I wanted: if (!(sampleString == null) && ! sampleString.Trim(). equals("")){

  • 1

    No. But the solution is the same... sampleString != null.

  • is yes. relax. :)

Browser other questions tagged

You are not signed in. Login or sign up in order to post.