I executed the following program and I am curious about the output i got in which the function output is getting printed first even if it was the variable i tried to print first.
class Baap{
public int h = 4;
public int getH(){
System.out.println("Baap "+h); return h;
}
}
public class Beta extends Baap{
public int h = 44;
public int getH(){
System.out.println("Beta "+h); return h;
}
public static void main(String args[]){
Baap b = new Beta();
System.out.println(b.h+" "+b.getH());
Beta bb = (Beta)b;
System.out.println(bb.h+" "+bb.getH());
}
}
The output was as follows
Beta 44
4 44
Beta 44
44 44
Can somebody help me understand why the function block gets executed first?
Your System.out.println line prints a String.
The String is evaluated at run-time as b.h + " " + b.getH(), so it concatenates b.h, space and the result of the method b.getH(), so it calls getH() which prints Beta 44, then prints the result 4 44.
When you call a function, all of its parameters have to be evaluated first. In your case the only parameter to System.out.println is the expression b.h + " " + b.getH().
Since that is still an expression, the next step is to evaluate that expression, which means to determine the value of the expression. It consists of 2 plus operators which have 3 operands. In order to evaluate the plus operators the program has to evaluate the values of the operands.
The value of b.h evaluates to 4, because variables are resolved statically-ish in Java. The type of the variable b is Baap so we get 4.
The next value is " " which is already a literal so there's nothing to do.
After that we have the function call b.getH(). Function calls in Java are always resolved virtually, so we actually call the function called getH of the Beta type. This function only sees its own scope, where the variable h declared in the class Beta "shadows" the one declared in the class Baap, meaning the h variable of Baap is hidden to every member of Beta.
To evaluate the function call we have to execute the function which prints "Beta 44" and returns the value 44.
Now that we have values for all 3 operators we can evaluate the expression with the + operators. This results in the String "4 44" which now gets passed to System.out.println and finally printed on the screen.
Related
class Test{
int p = (p=1) + p; // ERR "Cannot reference a field before it is defined"
int q = (q=1) + this.q; //fine!
void f() {
int t = (t=1) + t; // fine!
}
}
In the first case I understand that: when assignment (or subsequent addition?) is performed, p is treated as not declared.
But why is it different within a method? OK t is not treated as uninitialized because (t=1) is performed before addition. OK, t is not a field, but it is also not declared at the moment!
Can I understand it somehow? Or I shall just memorize this difference?
Maybe this is also related a bit to the same:
static int x = Test.x + (x=1) + Test.x; // produces 2
void f() {
int y = y + (y=1) + y; // ERR local variable y may not have been initialized
}
Why 2? First (x=1) is somehow evaluated (x is not declared!!!), then it returns 1, now x is already assigned (!?) and contains 1, so both Test.x is 1, but (x=1) operator also returned 1 so result shall be 1 + 1 + 1 and 3 shall be (reassigned) into x as a result of evaluating Test.x + (x=1) + Test.x expression.
PARTIAL ANSWER: Actually, the results are implementation specific. JLS guarantees only the order in which operands of a binary operator are evaluated (left-to-right). But if we have binary operators (say, plus) with same priority, their order of evaluation is NOT guaranteed.
In my case plus operators are evaluated left-most first, this is why static "int x = Test.x (ZERO) + (x=1) + Test.x (IS 1 after (x=1));" is 0 + 1 + 1 (remember, x=1 is an operator that returns assigned value).
Again in my case within method "int y = y + (y=1) + y;" leftmost plus operator is evaluated first (giving error), but if JVM chose to evaluate second plus operator first, then it is guaranteed to evaluate its left operand first and (y=1) would make the y variable initialized (so the code would compile!)
I am still not sure why (x=1) is not treated as undeclared with fields. I vaguely remember that JLS allows undeclared variable in LHS (so any assignment works), but not in RHS (x++, int sth=x). I can memorize it using the following snippet:
class Test {
{ x = 7; } // fine! Initializer is like a regular method
int x;
static { y = 7; } // fine! Initializer is like a regular method
static int y;
P.S. This is surely not a duplicate of Default Values and Initialization in Java - there is no direct explanation there. Here we need not only default values (zero for int) rules, but a lot of different rules in a very COMPLEX combination (operator precedence, and especially some rare peculiarities of assignment!). Also I know that assignment precedence is lowest here and that assignment is an operator and it returns value!
Read on scope of local variable declarations in Java Language Specification. Your exact problem is described in Example 6.3-2. The description is this:
The following program causes a compile-time error because the initialization of local variable p is within the scope of the declaration of local variable p, but the local variable p does not yet have a value and cannot be used.
Maybe I wont be very detailed but I will give a try, you pointed at very good examples of variable life cycle in Java.
int p = (p=1) + p; // ERR "Cannot reference a field before it is defined"
in this case p is a class field, when the compiler load a class p is not initialized yet (first scan of a class so p is not loaded yet into memory and cannot be evaluated).
void f() {
int t = (t=1) + t; // fine!
}
in this case the compiler only load the definition of the function, no matter what is inside (I mean if there are not syntax errors and no the kind of error that every IDE can check this is ok). It might be a strange declaration but it's fine, it's not evaluated until you call the function and you initialize t inline.
static int x = Test.x + (x=1) + Test.x; // produces 2
in this case x is a static variable, static 'things' are loaded before class so you can imagine that your compiler put the x field from where you wrote above everything. In this line you are saying that x is equals to 1, so 1 + 1 = 2. This is like doing something like this
static int x = 1;
x = Test.x + Test.x;
final int a=5;
System.out.println(a+1)
prints 6 whereas System.out.println(a++) or a=a+1 and then s.o.p(a) would give error.
Why would it print 6 when final values cant be changed?
Both a++ and a=a+1 assign a new value to a.
a+1 does not: it just evaluates to 1 more than the value in a.
Evaluating the statements:
System.out.println(a);
System.out.println(a+1);
System.out.println(a);
will show that the value of a is the same before and after. Doing the same with a++ or a=a+1 in the middle statement (obviously making a non-final first) will show that a is changed.
This should be no more surprising than System.out.println(5+1) printing 6, whilst leaving the values of 5 and 1 unchanged.
Because you never modify a in your example. You print the result of a+1. If you print a afterwards you'll see that it is still 5.
It is basically
int a = 5;
int b = a+1;
System.out.println(b); // prints 6
System.out.println(a); // still prints 5
I found this in one of the Java programming quiz question.
public class Calculator {
public static void main(String[] args) {
int i = 0;
Calculator c = new Calculator();
System.out.print(i++ + c.opearation(i));
System.out.print(i);
}
public int operation(int i) {
System.out.print(i++);
return i;
}
}
Executing above snippet gives me the result of 121. I'm expecting it to be 111. I'll explain how I interpreted it.
+ addition operator would get executed from right to left (ref: operator precedence). So, c.operation(0) is invoked first and it prints the value 1 instead I'm expecting the value to be 0 since System.out.print prints the value of i first and then increments the i value since it is a post increment operator.
Secondly, the i value 1 is returned to the main and the statement System.out.print(i++ + 1) gets executed now. And since i has post increment operator it should have executed like 0 + 1 and produced the result 1 insted it printed result as 2.
Thirdly, the i value is now incremented to 1 and this gets printed as expected.
In short, I'm expecting the value to be printed as 011 but I got the result as 121. I'm not sure where my interpretation goes wrong.
Additive Operators
The additive operators have the same precedence and are syntactically
left-associative (they group left-to-right).
int i = 0;
System.out.print(i++ + c.operation(i));
evaluate i++, get left operand 0, and increment i to 1.
pass i(1) to c.operation(i), execute System.out.print(i++). Print 1 then return 2(right operand).
i++ + c.operation(i) ---> 0 + 2, print 2.
print 1.
I was going through some exercises but I am confused in this one:
public static int f (int x, int y) {
int b=y--;
while (b>0) {
if (x%2!=0) {
--x;
y=y-2;
}
else {
x=x/2;
b=b-x-1;
}
}
return x+y;
}
What is the purpose of b=y--?
So, for example, x=5 and y=5
when we first go inside of while loop (while (b>0)) will b = 4 or 5? When I am running the code in my computer b is 5. And the return is 3. It is really unclear to me. Sorry if I am unclear in my question.
int b=y--; first assignes b=y and then decrements y (y--).
Also take a look at the prefix/postfix unary increment operator.
This example (taken from the linked page) demonstrates it:
class PrePostDemo {
public static void main(String[] args){
int i = 3;
i++;
// prints 4
System.out.println(i);
++i;
// prints 5
System.out.println(i);
// prints 6
System.out.println(++i);
// prints 6
System.out.println(i++);
// prints 7
System.out.println(i);
}
}
The difference between a post-increment/decrement and a pre-increment/decrement is in the evaluation of the expression.
The pre-increment and pre-decrement operators increment (or decrement) their operand by 1, and the value of the expression is the resulting incremented (or decremented) value. In contrast, the post-increment and post-decrement operators increase (or decrease) the value of their operand by 1, but the value of the expression is the operand's original value prior to the increment (or decrement) operation.
In other words:
int a = 5;
int b;
b = --a; // the value of the expression --a is a-1. b is now 4, as is a.
b = a--; // the value of the expression a-- is a. b is still 4, but a is 3.
Remember that a program must evaluate expressions to do everything. Everything is an expression, even just a casual mention of a variable. All of the following are expressions:
a
a-1
--a && ++a
System.out.println(a)
Of course, in the evaluation of expressions, operator precedence dictates the value of an expression just as the PEMDAS you learned in grade school. Some operators, such as increment/decrement, have side effects, which is of course great fun, and one of the reasons why functional programming was created.
I believe b would equal 5 entering the loop because
b=y--;
When the "--" is behind the variable it decrements it after the action.
It's poor coding, as it can confuse new programmers.
The function, assuming it is passing by value, like in the example above (as opposed to passing by reference) takes a copy of y, decrements it, and assigns it to b. It does not alter the argument passed to the function when it was called.
Post increment
x++;
x += 1;
Post decrement
x--;
x -=1;
Pre increment : ++x;
Pre decrement : --x;
According to the Head First Java:
Difference between x++ and ++x :
int x = 0; int z = ++x;
Produces: x is 1, x is 1
in x = 0; int z = x++;
Produces: x is 1, z is 0
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.