Java Ternary without Assignment

20,243

Solution 1

Nope you cannot do that. The spec says so.

The conditional operator has three operand expressions. ? appears between the first and second expressions, and : appears between the second and third expressions.

The first expression must be of type boolean or Boolean, or a compile-time error occurs.

It is a compile-time error for either the second or the third operand expression to be an invocation of a void method.

[EDIT]

Since you asked about reflection, here's a solution. I'm not recommending this. I'm posting it only because you asked.

public class MyCall
{

    public void a(){System.out.println("a");}
    public void b(){System.out.println("b");}

    public static void main(String... args)
    {
        new MyCall().go();
    }

    public void go()
    {
        Class<? extends MyCall> class1 = this.getClass();
        Method aMethod = class1.getMethod("b", null);
        Method bMethod = class1.getMethod("a", null);
        Object fake = false ? aMethod.invoke(this, null) : bMethod.invoke(this, null);
        Object fake2 = true ? aMethod.invoke(this, null) : bMethod.invoke(this, null);
    }
}

At the end of the day you've got to ask yourself if being succint improves your code's readability (think for-each loop). None of these solutions improve the code's readability IMHO. If I were you I'd rather go with this.

if(condition)
    a();
else
    b();

I'm actually for including braces even when loops only contain a single line, but since you're going after crisp code, the snippet above should do.

Solution 2

No, you can't do this like this.

You can prefer this style if do not like make it more statements.

if(bool1 && bool2) voidFunc1(); else voidFunc2();

In ternary operator, Operands are required to be non-void expressions; i.e. they must produce some actual value.

Solution 3

If you really-really want to use ternany operation, then there is one hack. BUT this is very bad code, intended only for showing abilities of language. I would never recommend to put this code in production or even show to your friends.

int dummy = (bool1 && bool2) ? new Object(){
        public int hashCode() {
            yourFunction1();
            // ...
            yourFunctionN();
            return 0;
        };
    }.hashCode() : new Object(){
        public int hashCode() {
            yourAnotherFunction1();
            // ...
            yourAnotherFunctionN();
            return 0;
        };
    }.hashCode();

Solution 4

Is there a way to do a java ternary operation without doing an assignment or way to fake the assignment?

OK, so when you write a statement like this:

    (bool1 && bool2) ? voidFunc1() : voidFunc2();

there are two distinct problems with the code:

  1. The 2nd and 3rd operands of a conditional expression1 cannot be calls to void methods. Reference: JLS 15.25.

  2. An expression is not a statement, unless it is either and assignment expression OR a method call OR a object creation. Reference: JLS 14.8.

In fact, the second of these problems is a syntax error and I would expect any mainstream Java compilers to report it instead of the first problem. The first problem would only reveal itself if you did something like this:

    SomeType dummy = (bool1 && bool2) ? voidFunc1() : voidFunc2();

or

    gobble((bool1 && bool2) ? voidFunc1() : voidFunc2());

where gobble is a method that does nothing ... except "consume" the value of its argument.

AFAIK, there is no context in which the original expression is acceptable.

However, there are ways to wrap the void functions so that they can be called in a conditional expression. Here is one:

 int dummy = (bool1 && bool2) ? 
     () -> {voidFunc1(); return 0;} : 
     () -> {voidFunc2(); return 0;};

1 - "Conditional expression" is the primary term used for this construct in the Java Language Specification. It is called the "ternary conditional operator" in Oracle Java Tutorial.

Share:
20,243
James Oravec
Author by

James Oravec

I like egg rolls.

Updated on July 09, 2022

Comments

  • James Oravec
    James Oravec almost 2 years

    Is there a way to do a java ternary operation without doing an assignment or way to fake the assingment?

    I like how succinct ternary code looks when doing a bunch of if/then/elses.

    I'm hoping to be able to call one of two void functions based on a boolean algebra statement.

    Something like:

    (bool1 && bool2) ? voidFunc1() : voidFunc2();

    My functions are of return type void, so if there is a way to fake this in an assignment to make it work, then I"m okay with that... I would like to see how to do it though :)