Search code examples
javacompilation

Why does JVM convert an `OR` to `AND`?


I am checking if an object is having an epoch pattern or is of type Long. So I wrote this in Java 8:

if(currentValue.toString().matches(EPOCH_PATTERN.pattern()) || 
currentValue instanceof Long) 
        this.setValue(Long.valueOf(currentValue.toString()));
      else
        this.setValue(currentValue);

and JVM compiled it to

if (!currentValue.toString().matches(EPOCH_PATTERN.pattern()) && 
!(currentValue instanceof Long)) {
                this.setValue(currentValue);
            } else {
                this.setValue(Long.valueOf(currentValue.toString()));
            }

This is definitely not what I expected when I wrote the code. How does OR get changed to AND. Am I making a fundamental mistake here?


Solution

  • Keep in mind this:

    • If you think that your logic is better then a code that was revied and tested by hundreds, then you are wrong
    • If you think there is a bug in an open-source code then think twice, highly possible that you are wrong

    Lets suppose this:

    A: currentValue.toString().matches(EPOCH_PATTERN.pattern()
    B: currentValue instanceof Long
    

    Your code

    A = 0 and B = 1 ---> 0 || 1 = 1 ---> setValue(Long...)
    A = 1 and B = 0 ---> same case
    A = 1 and B = 1 ---> same case
    A = 0 and B = 0 ---> 0 || 0 = 0 ---> setValue(currentValue)
    

    JVM code

    A = 0 and B = 1 ---> !0 && !1 ---> 1 && 0 = 0 ---> setValue(Long...)
    A = 1 and B = 0 ---> !1 && !0 ---> same case
    A = 1 and B = 1 ---> !1 && !1 ---> same case
    A = 0 and B = 0 ---> !0 && !0 ---> 1 && 1 = 1 --> setValue(currentValue)