Exiting the method from a ternary operator - java

So somewhere in one of my methods, I'm calling another method called foo() and want to use ternary operator to write a short-hand if statement based on what foo()returns. Here's the foo() method:
public boolean foo(String s){
if (!s.contentEquals("")){
System.out.println(s);
return true;
}
return false;
}
The case in which I want to use the ternary operator with the return value of foo() looks like this:
(...)
boolean bool = foo("abc") ? null : return;
(...)
I basically want the method to do nothing and keep going if foo() returns true, and exit out if it returns false.
Is there a way to achieve this using the ternary operator?

The conditional operator ("the operator with three operands" is `a silly way to describe it) is an operator, and all three of its operands need to be expressions.
"return" is not an expression, it is a statement, and therefore can't be used where an expression is needed.
Furthermore, the result of an expression involving the conditional operator is itself an expression, and cannot be used where a statement is needed.
Expressions and statements are different entities in Java.

Related

Ternary operator in print statement of java [duplicate]

This question already has answers here:
Unexpected type resulting from the ternary operator
(4 answers)
Closed 4 years ago.
I was playing with ternary operator and noticed something odd. I have code below:
class Main {
static void foo(int a){
System.out.println("int");
}
static void foo(String a){
System.out.println("String");
}
static void foo(Object a){
System.out.println("object");
}
public static void main(String[] args) {
foo(2==3 ? 0xF00:"bar");
System.out.println((2==3 ? 0xF00:"bar").getClass().getName());
}
}
Which results in
object
java.lang.String
First line of result shows that this instruction passed to foo method with object parameter.
Second line that the instruction itself results in String.
Question:
Why if result is String compiler decides to go with Object?
Is this because of the type ambiguity?
If yes then why getting class name returned java.lang.String?
In Java, you have compile time type information and you have run time type information. Compile time type information is what the compiler can deduce about the type of a value or expression just by looking at it, but without executing it. When the compiler sees the expression
2 == 3 ? 0xF00 : "bar"
It does not know whether 2 == 3 will be true or false, because it does not execute code. So all it knows is that the result can be an Integer, or a String. So when the time comes to pick which foo method to call, it picks the one that accepts Object, since that is the only one that it knows will work in both scenarios.
However, when the code is actually running, 2 == 3 will be false, and the result will be a String, whose getClass() method will return String.class. And that is what you need to note: getClass() does not return the type that the variable had at compile time, but it returns the actual type of the object that the variable holds at run time. i.e.
Object o = "Hello!";
System.out.println(o.getClass());
will print java.lang.String, because even though to the compiler it is an Object, at run time it is actually a String.
You can skip to Summary if not interested in reading.
Refer the JavaDoc here: https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.25
Under 15.25.3. Reference Conditional Expressions It says:
The type of the conditional expression is the
result of applying capture conversion
For capture conversion : https://docs.oracle.com/javase/specs/jls/se8/html/jls-5.html#jls-5.1.10
Summary:
For type determination, capture conversion is used, wherein for your example int is first boxed to Integer and then the closest common super class of Integer and String is fetched, which is Object class. So the type for the Conditional Expression is Object and so the method with Object as parameter is called.
Now for second part, the Conditional operator is evaluated first, then it is unboxed and then .getClass() is evaluated. So it prints java.lang.String.
This is also documented here: https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.25
Under 15.25. Conditional Operator ? :
At run time, the first operand expression of the conditional
expression is evaluated first. If necessary, unboxing conversion is
performed on the result.
At compile stage, the compiler noticed that the result of 2 == 3 ? 0xF00 : "bar" could be int or String. To be compatible with both, it decide to call foo(Object a).
At runtime, the result of 2 == 3 ? 0xF00 : "bar" is String bar.

TernaryOperator (? :) for functions Java. How close we can get? [duplicate]

This question already has answers here:
Java: Ternary with no return. (For method calling)
(6 answers)
Closed 4 years ago.
Java has ternary operator, that works on variables:
(a > 0) ? b++ : c--;
What is a, b, c were functions? I tested something like (a returns boolean, b & c are void):
a() ? b() : c();
but even my Eclipse does not allow that.
How close could I get to this programmatically (to generate functionality to make this with minimum amount of lines)?
I know in other languages like Javascript I could just pass function as parameter, but I have not met similar in Java.
Edit
We have gone in discussion to sidewals because of bad constellation of question, but here is what I want, and it is a real world problem:
What I want to achieve is single-liner to call second or third function based on return value of the first.
With minimum amount of code of course.
What I had tried was that ternary that is made to other things, that I know now.
As others have already explained, the conditional operator is an expression that evaluates to a value, and can thus not be applied to void methods.
If you need a one-liner discarding any return values, use a simple if-else:
if (a()) b(); else c();
If you go through Java Ternary Operator let's you assign a value to a variable based on a boolean expression — either a boolean field, or a statement that evaluates to a boolean result (Its used for assignment). In above you are trying to call functions with return value void that is not allowed in Ternary Operator in java.
The ternary operator, also known as the conditional operator, can be
used as an alternative to the Java if/then/else syntax
You can only use the ternary operator as an expression, not a statement. It's not simply alternative syntax for an if-else - the point is that if a() returns true, the entire expression resolves to the result of b(), else the entire expression resolves to the result of c().
As such, it doesn't make sense if b and c return void. They must return something, and the most specific type that they share will be the resulting type of the whole expression.

Conditional method calling by abusing ternary wrapped in if statement?

Recently I was doing a code review and came across this guy:
if(!sharePermission.isExpired() ? activePermissions.add(sharePermission) : expiredPermissions.add(sharePermission));
Basically using a ternary expression to call methods that return a boolean value and wrapping it in an if(...) statement to satisfy the requirement of being a standalone statement. Is this more or less valid than
if(!sharePermission.isExpired())
activePermissions.add(sharePermission);
else
expiredPermissions.add(sharePermission);
if you really need to condense your code to one line? Is any sort of extra space allocated for the value returned from the ternary expression when wrapped in the if(...) ?
I'm not a fan of either of them, just curious.
It's an abuse of the if statement to do that, never mind the conditional expression.
It would be cleaner to write either a full if statement, or to use the conditional operator to select a list to add to:
List<Permission> list = isExpired() ? expiredPermission : activePermission;
list.add(sharePermission);
There is no assignment happening, only an evaluation of a boolean condition. No extra memory is allocated for the result of the evaluation.
Using a ternary expression to emulate a ternary statement, however, is grossly unorthodox. It is going to reduce readability of your code, without bringing any additional benefit. Hence, using a plain if with an else is a better alternative.
Note that if activePermissions and expiredPermissions are of the same type, you can use a ternary expression to decide between the targets of the add call, as follows:
(sharePermission.isExpired() ? expiredPermissions : activePermissions).add(sharePermission);
The ternary equivalent for the if..else that you are looking for is something like -
(!sharePermission.isExpired() ? activePermissions : expiredPermissions).add(sharePermission); // no if here
is equivalent to
if(!sharePermission.isExpired()) {
activePermissions.add(sharePermission);
}
else {
expiredPermissions.add(sharePermission);
}

Is there any reason for Eclipse showing assignment variables in while loops as valid?

I've been punked numerous times while working on Java in eclipse when I write a while loop like so:
while (recsFinished = true)
When in reality I wanted
while (recsFinished == true)
It's a pretty simple mistake, but it happens to me a lot and it totally throws off the program. And the reason it does is because Eclipse doesn't even throw up a warning when I write the assignment as opposed to the equality equation. This leads me to believe there has to be some reason for a while loop with an assignment equation to exist, but why? I can't think of a single use!
Such assignments are popular in C and C++ (particularly within if statments) and have found themselves part of Java too.
Some folk put the literal on the left hand side: while (true == recsFinished) instead and I'm tempted to suggest that you adopt this programming style only that I personally find it obfuscating. This will issue a compiler error if = is used by accident.
Note well though that comparison to true is redundant. Drop it entirely and use while (recsFinished) instead.
It compiles, since it's valid Java syntax.
It's equivalent to :
recsFinished = true;
while (recsFinished) {
....
recsFinished = true;
}
Which is equivalent to
recsFinished = true;
while (true) {
....
recsFinished = true;
}
which would give you an infinite loop.
It is entirely possible to set a value in the expression of you while loop. If you do this your expression will be evaluated which is alway true because you reset it to true everytime you do a loop.
In most programming languages, the operator = return the assigned value after calling it.
whcih means if you want to assign a variable in every iteration and the value of this variable is the condition then you will use = in the loop condition instead of ==
Example
boolean a, b;
b = true;
while(a = b){
// Some crazy things using a & b
// loop ends when b == false at the end of an iteration
}
To answer your question; It's valid because the specification says so.
You can call a method with an expression,
15.12. Method Invocation Expressions
A method invocation expression is used to invoke a class or instance method.
MethodInvocation:
MethodName ( ArgumentList opt )
ArgumentList:
Expression
ArgumentList , Expression
and an assignment is an expression,
15.26. Assignment Operators
There are 12 assignment operators; all are syntactically right-associative (they group right-to-left). Thus, a=b=c means a=(b=c), which assigns the value of c to b and then assigns the value of b to a.
AssignmentExpression:
ConditionalExpression
Assignment

Statements inside ?: expression

I'm learning scala and trying to understand the following sentence:
In Java you can't put statements inside a ?: expression
Can someone explain this to me, perhaps with an example and maybe in the context of Scala?
Java has a ternary conditional operator inherited from C, it looks like this:
int x = some_condition ? 1 : 2;
x will be equal to 1 if some_condition is true, and to 2 otherwise. Java requires that arguments to this operator are expressions, i.e. things which result in concrete values. For example, method call or constant literal are expressions, but a loop or a conditional statement or a variable definition are not expressions because they do not have meaningful value. This means that you cannot return, say, variable definition from a function, but you can return result of method call.
Scala does not have ternary operator. But it does not need one because in Scala everything is expression. Even loops - they result in a special value of Unit type. Conditionals are also expressions, they return a value of common supertype of all branches. Because of this you can use plain conditional "statement" instead of ternary operator. This Scala snippet is equivalent to Java one above:
val x = if (some_condition) 1 else 2
Moreover, in Scala every block is an expression too (its value is the value of the last line in the block), so you can have statements, for example assignments, inside the "ternary operator":
val x = if (some_condition) {
val y = some_computation()
y*2
} else {
val z = another_computation()
z + 3
}
More generally, you can't put arbitrary statements in any expression, not just the conditional expression.
A method's block is a list of statements. A statement is made up of other statements and/or expressions. But expressions, being the building blocks of statements, do normally not contain statements.
Well, there is one exception: a class creation expression of the form
new C(argument list) { class definition }
This creates at compile time a new class that is a subclass of C and at runtime an instance of that class. Hence it would be possible to write something like:
cond ? (new Object() {
public int get() { System.out.println("Hi"); return 42; }
}).get()
: 0
to smuggle a statement into an expression.
The thing you put inside the ?: expression are other expressions. The first one must evaluate to a boolean, and the second and third evaluate to the same type (int, String, etc.). A statement is something that is executed, an expression is something that results in a value. It gets confusing because you can put executable stuff inside an expression.

Categories

Resources