Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can (a==1 && a==2 && a==3) evaluate to true in Java?

Tags:

java

We know it can in JavaScript.

But is it possible to print "Success" message on the condition given below in Java?

if (a==1 && a==2 && a==3) {
    System.out.println("Success");
}

Someone suggested:

int _a = 1;
int a  = 2;
int a_ = 3;
if (_a == 1 && a == 2 && a_ == 3) {
    System.out.println("Success");
}

But by doing this we are changing the actual variable. Is there any other way?

like image 464
Taylor Sen Avatar asked Oct 15 '22 11:10

Taylor Sen


People also ask

Can a == 1 && a == 2 && a == 3 ever evaluate to true in JavaScript?

The question is — Can (a==1 && a==2 && a==3) ever evaluate to true? The answer is — Yes.

What is result of True == 1 in JavaScript?

It started with: Boolean type take only two literal values: true and false. These are distinct from numeric values, so true is not equal to 1, and false is not equal to 0. I know, that every type in JavaScript has a Boolean equivalent.

What is == in JavaScript?

The equality operator ( == ) checks whether its two operands are equal, returning a Boolean result. Unlike the strict equality operator, it attempts to convert and compare operands that are of different types.


Video Answer


3 Answers

Yes, it's quite easy to achieve this with multiple threads, if you declare variable a as volatile.

One thread constantly changes variable a from 1 to 3, and another thread constantly tests that a == 1 && a == 2 && a == 3. It happens often enough to have a continuous stream of "Success" printed on the console.

(Note if you add an else {System.out.println("Failure");} clause, you'll see that the test fails far more often than it succeeds.)

In practice, it also works without declaring a as volatile, but only 21 times on my MacBook. Without volatile, the compiler or HotSpot is allowed to cache a or replace the if statement with if (false). Most likely, HotSpot kicks in after a while and compiles it to assembly instructions that do cache the value of a. With volatile, it keeps printing "Success" forever.

public class VolatileRace {
    private volatile int a;

    public void start() {
        new Thread(this::test).start();
        new Thread(this::change).start();
    }

    public void test() {
        while (true) {
            if (a == 1 && a == 2 && a == 3) {
                System.out.println("Success");
            }
        }
    }

    public void change() {
        while (true) {
            for (int i = 1; i < 4; i++) {
                a = i;
            }
        }
    }

    public static void main(String[] args) {
        new VolatileRace().start();
    }
}
like image 328
Erwin Bolwidt Avatar answered Oct 24 '22 07:10

Erwin Bolwidt


Using concepts (and code) from a brilliant code golf answer, Integer values can be messed with.

In this case, it can make ints casted to Integers be equal when they wouldn't normally be:

import java.lang.reflect.Field;

public class Test
{
    public static void main(String[] args) throws Exception
    {
        Class cache = Integer.class.getDeclaredClasses()[0];
        Field c = cache.getDeclaredField("cache");
        c.setAccessible(true);
        Integer[] array = (Integer[]) c.get(cache);
        // array[129] is 1
        array[130] = array[129]; // Set 2 to be 1
        array[131] = array[129]; // Set 3 to be 1

        Integer a = 1;
        if(a == (Integer)1 && a == (Integer)2 && a == (Integer)3)
            System.out.println("Success");
    }
}

Unfortunately it's not quite as elegant as Erwin Bolwidt's multithreaded answer (as this one requires Integer casting), but still some fun shenanigans take place.

like image 88
phflack Avatar answered Oct 24 '22 09:10

phflack


In this question @aioobe suggests (and advise against) the use of C preprocessor for Java classes.

Although it is extremely cheaty, that's my solution:

#define a evil++

public class Main {
    public static void main(String[] args) {
        int evil = 1;
        if (a==1 && a==2 && a==3)
            System.out.println("Success");
    }
}

If executed using the following commands it will output exactly one Success:

cpp -P src/Main.java Main.java && javac Main.java && java Main
like image 52
Pado Avatar answered Oct 24 '22 09:10

Pado