Does promotion occur before increment in Java? - java

I've seen this question in OCA questions and need to know why it outputs 90 and not 100.
Here is the code:
int x = 9;
long y = x * (long) (++x);
System.out.println(y);
So, what I think this would do is, firstly, increment x (because that's what happens at first right?) and then it would do the type promotion and take left x which is 10, turn it into long and multiply those two longs. Right?

No. The operands of each operator are evaluated from left to right. Therefore the first operand of the * operator, x, is evaluated before the second operand (long) (++x). Therefore 9 is multiplied by 10.

Related

How are y=x++ and y=x-- different when the assignment operators has the least priority?

I'm new to java.
Just found out that in the expression,
y=x++, y assumes the value of x and x becomes +1.
Forgive me if I sound stupid, but according to the order of precedence, assignment operators is at the end. So isn't x++ supposed to happen first followed by the assignment. Thanks in advance.
Q: So isn't x++ supposed to happen first followed by the assignment.
A: Yes. And that is what happens. The statement y = x++; is equivalent to the following:
temp = x; // | This is 'x++'
x = x + 1; // | (note that 'temp' contains the value of 'x++')
y = temp; // This is the assignment.
But as you see, the order of the operations (++ and =) doesn't affect what the operations actually do.
And therefore ...
Q: How are y=x++ and y=x-- different when the assignment operators has the least priority?
A: They aren't.
Operator precedence and evaluation order are two different concepts and they're not related.
If you have a() + b() * c(), that doesn't mean that b() and c() get invoked first because * has a higher precedence than +. a() still gets evaluated first. Evaluation order is typically left-to-right unless stated otherwise.
The Java programming language guarantees that the operands of
operators appear to be evaluated in a specific evaluation order,
namely, from left to right.
https://docs.oracle.com/javase/specs/jls/se14/html/jls-15.html#jls-15.7
y=x++ is assigning the value of x to y and then x gets incremented. The x++ operation is called a post-increment.
Here's some code that you can run for illustration:
int x = 0;
System.out.println("Illustration of post-increment");
System.out.println(x);
System.out.println(x++);
System.out.println(x);
int y = 0;
System.out.println("Illustration of pre-increment");
System.out.println(y);
System.out.println(++y);
System.out.println(y);

What is the difference += and +?

I was asked a question what the difference is between having counter += 5 and counter + 5 in the java programming language. I said they essentially do the same thing but I did not know how to explain why. I felt one was considered a shorthand representation of the same problem but now thinking about it more, I feel I am not correct. Can anyone give me a simple explanation the difference between them?
counter += 5 modifies counter. counter += 5 can be used as a statement (e.g. line of code) on its own, because it does something (increments counter by 5).
counter + 5 does not modify anything. counter + 5 can only be used as an expression within a statement, because it doesn't do anything on its own.
Here is some code that demonstrates the difference:
int counter = 1;
System.out.println(counter + 5); // 6
System.out.println(counter); // 1
// counter + 5; // not a valid statement
counter += 5; // counter is now 6
System.out.println(counter); // 6
System.out.println(counter += 5); // 11
System.out.println(counter); // 11
counter += 5 is assigning the value of whatever counter was plus 5 to the counter variable while counter+5 is return the result of 5 plus counter but the counter variable stays the same.
+= operator
For example you have a a variable counter that equals 3. When you do counter += 5, you are actually assigning a new value to the variable counter. so if counter was 5 and you do counter+=3, counter will now equal 8.
+ operator without the equal
In this case if your counter equals 3. when you do counter+3 it will return 8 for that instance but your counter will still be 3.
Code to demonstrate the differences:
int counter = 3;
counter += 5;
int y = 0;
/*this will return 8, since the result of 5 and counter was newly assigned to
counter*/
System.out.println(counter);
//resetting counter value.
counter =3;
y = counter+5;
//here counter still remains at 3, because there wasn't anything assigned to it
System.out.println(counter);
//will return 8, because you assigned the result of counter and 5 to y.
System.out.println(y);
Only the JLS holds the true answer!
(Assuming count is a numeric type. If it's a String, for example, then everything everyone told you above is wrong at the time I wrote this.)
+= operator
JLS 15.26.2 Compound Assignment Operators:
A compound assignment expression of the form E1 op= E2 is equivalent to E1 = (T) ((E1) op (E2)), where T is the type of E1, except that E1 is evaluated only once.
following,
[...] the saved value of the left-hand variable and the value of the right-hand operand are used to perform the binary operation indicated by the compound assignment operator.
[...] the result of the binary operation is converted to the type of the left-hand variable, subjected to value set conversion (§5.1.13) to the appropriate standard value set (not an extended-exponent value set), and the result of the conversion is stored into the variable.
(emphasis mine). In the above above notation, E1 and E2 will perform the operation indicated by += (meaning E1 + E2). The result is stored in E1.
+ operator
JLS 15.18.2. Additive Operators (+ and -) for Numeric Types:
The binary + operator performs addition when applied to two operands of numeric type, producing the sum of the operands.
Note that there is no assignment here.
counter += 5 is the one that is shorthand, but it's shorthand for counter = counter + 5. counter + 5 is just an expression, what you get is a value that is 5 greater than the value of counter, but this value is just left behind and nothing is done with it. In order for something else to happen, an additional operator needs to be present, such as the =, or assignment operator. This operator takes an expression on the right hand side and an identifier on the left, evaluating the expression and assigning the result to the identifier. Without assignment, values don't change, and even when you use methods that seem to change values without assignment (String.append() for example) there is an assignment hidden in the code of the function. As an added fact, counter += 5 can be reduced (if you really want to call it reducing it) to counter++ used 5 times.

x = x++ doesn't increment because the ++ is applied after the assignment?

From page 280 of OCP Java SE 6 Programmer Practice Exams, question 9:
int x = 3;
x = x++;
// x is still 3
In the explanation we can read that:
The x = x++; line doesn't leave x == 4 because the ++ is applied
after the assignment has occurred.
I agree that x is 3, I understand post-incremenation.
I don't agree with the explanation. I would replace "after" with "before".
I thought it works like this:
x is 3.
x++ is executed. I see this post-increment operator as a function:
int operator++() {
int temp = getX();
setX(temp + 1);
return temp;
}
So, after x++ execution, x is 4, but the value returned from x++ expression is 3.
Now, the assignment =. Simply write returned 3 to x.
So, in my eyes ++ is applied before the assignment has occurred. Am I wrong?
...the ++ is applied after the assignment has occurred.
Okay, hold on. This is actually confusing and perhaps suggests an incorrect behavior.
You have the expression†:
x = ( x++ )
What happens is (JLS 15.26.1):
The expression on the left-hand side of the assignment x is evaluated (to produce a variable).
The expression on the right-hand side of the assignment ( x++ ) is evaluated (to produce a value).
The evaluation of the right-hand side is: x is post-incremented, and the result of the expression is the old value of x.
The variable on the left-hand side, x, is assigned the value produced by the evaluation of the right-hand side, which is the old value of x.
So the post-increment happens before the assignment.
(Therefore, as we know, the value of x after executing the statement x = x++; is the same as the value of x before executing the statement, which is 3.)
So, in my eyes ++ is applied before the assignment has occurred. Am I wrong?
You are right.
Technically, the way it is specified is that x++ is evaluated before its result is stored and during the evaluation of the assignment operator. So x++ can be interpreted as happening either before or during the assignment. Not after, so the book appears to be wrong either way.
Just for the heck of it, we may also look at some bytecode:
/* int x = 3; */
iconst_3 // push the constant 3 on to the stack : temp = 3
istore_0 // pop the stack and store in local variable 0 : x = temp
/* x = x++; */
iload_0 // push local variable 0 on to the stack : temp = x
iinc 0 1 // increment local variable 0 by 1 : x = x + 1
istore_0 // pop the stack and store in local variable 0 : x = temp
The iinc happens before the istore.
†: The parentheses have no effect on the evaluation, they are just there for clarity.
Reaching over to the official spec:
postfix ++ section: https://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.14.2
assignment operator section: https://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.26.1
In terms of assignment, this is simple assignment, so we hit case 3:
First, the left-hand operand is evaluated to produce a variable -- x
no errors -> the right-hand operand is evaluated -- x++
"the value of the right-hand operand is converted to the type of the left-hand variable, is subjected to value set conversion (§5.1.13) to the appropriate standard value set (not an extended-exponent value set), and the result of the conversion is stored into the variable"
So in step 2, the postfix operator should get resolved, and then in step 3, x gets assigned its original value again:
call: x = x++;
interframe: LHS is variable 'x'
interframe: RHS caches return value as 3
interframe: x is incremented to 4
interframe: RHS cached value '3' is returned for assignment
interframe: variable x is assigned value 3
call result: x = 3
So I think you're right in that the book is wrong, and it might be worth contacting the authors or publisher to have a correction published (or added to an errata page, etc)
x++ means "use x and then increment x."
You can also use ++x, which means "increment x and then use x."
More easily, however, you can simply do
x += 1;
++x is called preincrement while x++ is called postincrement.
int x = 3;
x = ++x;
exemple
int x = 5, y = 5;
System.out.println(++x); // outputs 6
System.out.println(x); // outputs 6
System.out.println(y++); // outputs 5
System.out.println(y); // outputs 6

Strange behaviour of the increment operators in Java?

I have to pieces of code:
int m = 4;
int result = 3 * (++m);
and
int m = 4;
int result = 3 * (m++);
After the execution m is 5 and result is 15 in the first case, but in the second case, m is also 5 but result is 12. Why is this the case? Shouldn't it be at least the same behaviour?
I'm specifically talking about the rules of precedence. I always thought that these rules state that parantheses have a higher precedence than unary operators. So why isn't the expression in the parantheses evaluated first?
No - because in the first case the result is 3 multiplied by "the value of m after it's incremented" whereas in the second case the result is 3 multiplied by "the initial value of m before it's incremented".
This is the normal difference between pre-increment ("increment, and the value of the expression is the value after the increment") and post-increment ("remember the original value, then increment; the value of the expression is the original one").
The difference is when the result is assigned to m.
In the first case you have basically (not what it really does, but helps to understand)...
int result = 3 * (m=m+1);
In the second case you have
int result = 3 * m; m = m +1;
This is the definition of the operators: m++ evaluates to m, then increments m. It's a "post-increment". Parentheses around it don't change the fact that the operator evaluates to the variable, and also increments it afterward.
Think of it as "increment and get" and "get and increment." For instance, see AtomicInteger, which has the methods incrementAndGet() and getAndIncrement().

Java: += equivalence

Is:
x -= y;
equivalent to:
x = x - y;
No, they are NOT equivalent the way you expressed them.
short x = 0, y = 0;
x -= y; // This compiles fine!
x = x - y; // This doesn't compile!!!
// "Type mismatch: cannot convert from int to short"
The problem with the third line is that - performs what is called "numeric promotion" (JLS 5.6) of the short operands, and results in an int value, which cannot simply be assigned to a short without a cast. Compound assignment operators contain a hidden cast!
The exact equivalence is laid out in JLS 15.26.2 Compound Assignment Operators:
A compound assignment expression of the form E1 op= E2 is equivalent to E1 = (T)((E1) op (E2)), where T is the type of E1, except that E1 is evaluated only once.
So to clarify some of the subtleties:
Compound assignment expression doesn't reorder the operands
Left hand side stays on the left, right hand side stays on the right
Both operands are fully-parenthesized to ensure op has the lowest precedence
int x = 5; x *= 2 + 1; // x == 15, not 11
There is a hidden cast
int i = 0; i += 3.14159; // this compiles fine!
The left hand side is only evaluated once
arr[i++] += 5; // this only increments i once
Java also has *=, /=, %=, +=, -=, <<=, >>=, >>>=, &=, ^= and |=. The last 3 are also defined for booleans (JLS 15.22.2 Boolean Logical Operators).
Related questions
Varying behavior for possible loss of precision
Why doesn’t Java have compound assignment versions of the conditional-and and conditional-or operators? (&&=, ||=)
Yes, it is. This syntax is the same in most C-derived languages.
Not exactly. The reason it was introduced in C was to allow the programmer to do some optimizations the compiler couldn't. For example:
A[i] += 4
used to be compiled much better than
A[i] = A[i] + 4
by the compilers of the time.
And, if "x" has side effects, e.g "x++" then it is wildly different.

Categories