The question is from the famous SCJP 6 book
Given:
public class Dark {
int x = 3;
public static void main(String[] args) {
new Dark().go1();
}
void go1() {
int x;
go2(++x);
}
void go2(int y) {
int x = ++y;
System.out.println(x);
}
}
What is the result?
A. 2
B. 3
C. 4
D. 5
E. Compilation fails
F. An exception is thrown at runtime
The answer according to the book is:
✓ E is correct. In go1() the local variable x is not initialized.
My questions is why go1() cannot use instance variable x initialized as 6 on line 4 here?
Because the local variable x exists. If int x; were commented out, it will run fine and use the instance variable.
In Java all the local variables should be initialized if not it will give an error. But you shouldn't initialize parameters of a method.
if you don't have int x then this will be ok. because at that case compiler will use the local variable which is assigned for class level.
Related
public class Practice {
int x;
static int y;
void functionA() {
int y = 0;
System.out.println("inside non static method functionA()");
x = 10;
y = 30;
System.out.println(x);//10
System.out.println(y);//30
functionZ();
System.out.println(x);//10
System.out.println(y);//30
}
static void functionZ() {
System.out.println("inside static method functionZ()");
System.out.println("y: " + y);//prints 0, thought it was supposed to be 30?
}
public static void main(String[] args) {
Practice s = new Practice();
s.functionA();
}
}
Can someone explain why upon execution, inside functionZ(), y is printed as 0 and not 30? Before z is invoked, in functionA we've already set the value to 30. And since there is supposed to only be one copy of a static variable across all instances of an object, shouldn't it be 30?
Inside your functionA you defining a local variable y:
void functionA() {
int y = 0;
...
While you are in that function all access to y will go into this variable, so you set it to 30. This did however not impact the static variable y, which still has the value 0 and it is accessed from the static method functionZ.
To emphasize you want to access the static variable y rather than the local variable y, use the qualified identifier Practice.y.
There is a huge difference in global variable and local variable.
Global variables have the scope in the entire class.
Where as local variable have the the limited scope only within the method or the block in which it is declared.
Here you have declared static int y; which is global variable and can be accessed by functionZ().
Whereas the variable int y=0; declared in functionA() is a local variable, can only be accessed within the functionA() method itself. Meaning other methods DO NOT even know that variable even exists.
Lets say you remove static int y; and in funtionZ() method you will get an error beacuse it doesnt find any variable y
I'm facing some difficulties while trying to understand, what actually happens when we initiate an instance of a child class.
public class A {
2. public int x, y;
3. public A () { x=1; y=2; }
4. public int getx () { return x; }
5. }
6. public class B extends A {
7. public int x, z;
8. public B () { super(); x=3; y=4; z=5; }
9. public int getx () { return x; }
10. public int getz () { return z; }
11. }
12. public class Prob1 {
13. public static void main (String[] args){
14. A o1 = new A();
15. A o2 = new B();
16. B o3 = new B();
17. System.out.println(o1.x);
18. System.out.println(o1.getx());
19. System.out.println(o1.y);
20. System.out.println(o1.getz());
21. System.out.println(o2.x);
22. System.out.println(o2.getx());
23. System.out.println(o2.y);
I would love to here a detailed explanation of what is going on here exactly, but the main thing I can't understand is why line '21' prints the number 1, and line '23' prints the number 4.
Polymorphism applies to methods, not to instance variables.
Both lines 21 and 23 print the value of the instance variables of class A, since that's the compile time type of o2 (even though its runtime type is B).
21. System.out.println(o2.x);
The value of A's x member is 1 (set by the constructor public A () { x=1; y=2; }).
23. System.out.println(o2.y);
The value of A's y member is 4 (set by the constructor public B () { super(); x=3; y=4; z=5; }).
Note the B has an x instance variable that hides A's variable of the same name. Therefore B's constructor doesn't change A's x variable to 3. On the other hand, B doesn't have a y instance variable, so y=4; changes the value of A's y variable to 4.
BTW, line 20 has a compilation error. I had to comment it out in order to execute your code.
Also note that o2.getx() gives a different result than o2.x, since getx() is a method overridden by class B, so it returns B's instance variable x, whose value is 3 (since the runtime type of o2 is B).
I have a below code. The variable c and d are class variables and initially they were pointing to value 0, but when I did c=a* a; and d =b* b*b they printed value as 25 and 64 which is correct. so what I think now is that the c and d are now pointing to value 25 and 64 and they are class variables, so if I do j=c+d; it should give me 89 as j value, but it is giving me 0... why? I know if I use static with c and d variable it will give me 89 value... but why I should use static as c and d are global variables and there values are now updated to 25 and 64. Please let me know. Thanks.
public class BaiscSum {
int a=5;
int b=4;
int c;
int d;
int j;
public void square() {
c=a*a;
System.out.println(c);
}
public void cube() {
d=b*b*b;
System.out.println(d);
}
public void sum() {
j=c+d;
System.out.println(j);
}
public static void main(String[] args) {
BaiscSum squ= new BaiscSum();
squ.square();
BaiscSum cub = new BaiscSum();
cub.cube();
BaiscSum su = new BaiscSum();
su.sum();
}
}
You are using three separate instances of your class. This means that squ, cub, and su each have their own version of the class. Instead, use the same one instance, so that all changes will happen to the same instance.
public static void main(String[] args) {
BaiscSum sum= new BaiscSum();
sum.square();
sum.cube();
sum.sum();
}
If I do j=c+d; it should give me 89 as j value, but it is giving me
0. why?
Because you are referencing sum() with su object but you have not called cube() and square() on su instead you called it with cub and squ respectively.
Change to
BaiscSum su = new BaiscSum();
su.square();
su.cube();
su.sum();
It will give you the expected output.
Since all the variables you are using are instace so every object will have its own set of variable on their respective memory spaces and if you changed any one objects variable it will not effects other objects value.
This could clear more
As an explanation every object is assigned a seperate memory and so changes to the variable of one objects doesn't effect changes to other objects variable unless they are static. So in the third object c and d is not initialized for su object so jvm uses default value if int ie 0 giving you a sum of zero.
I understand the purpose of static keyword but regretfully I can't figure out this simple code. Don't know why? I'm expecting the answer to be really simple.
public class VariableScope {
int x=y;
static int y=5;
public static void main(String[] args) {
System.out.println(new VariableScope().x);
}
}
How x gets printed as 5 when y was assigned to it at an earlier stage?
The static initialization static int y = 5 happens during class loading.
The x = y assignment happens during the instance construction new VariableScope(); so at this point y has the value 5 already.
It's because order the lines of the code does not matter here. Static member is initialized first, then x is initialized.
Here is detailed specification of the initialization order: Java Language Specification 12.4.2. Detailed Initialization Procedure
I have been through this question on legality of forward references but not clear as to what is meant by forward references in Java language . Can someone please explain with the help of an example ?
This is specifically a compilation error. And its all about ordering of class variable declarations. Let's use some code for illustrative purposes:
public class ForwardReference {
public ForwardReference() {
super();
}
public ForwardReference echoReference() {
return this;
}
public void testLegalForwardReference() {
// Illustration: Legal
this.x = 5;
}
private int x = 0;
// Illustration: Illegal
private ForwardReference b = a.reference();
private ForwardReference a = new ForwardReference();
}
As you can see, Java allows you to reference a class variable in a class method, even if the declaration of the variable comes after the method. This is an example of a (legal) forward reference, and support for this is built into the Java compiler.
What you cannot do though, is declare a class variable 'a' that depends on another class variable 'b' that has not been declared yet. Dependent class variable declarations must appear in reverse order of their dependency.
On a tangent, Most, if not all IDE's will warn you if your code contains illegal reference errors.
Illegal forward references are covered in section 8.3.2.3 of the JLS.
It's basically just the order that things are read by the compiler, if you have
int c = 3
int a = b;
int b = 5;
the compiler will read it from top to bottom, so it will se the first line, which declares a variable 'c', and assigns it to 3, and that is fine, then it will encounter the second line, which declares a variable 'a', and then tries to assign it to 'b'.
But now, the compiler has a problem: What is this 'b' thing? It has only yet learned about 'c', and just recently 'a', but it has no knowledge anything called 'b', since to the compiler, it has not yet been declared. So then, since the compiler can't handle all the confusion, it stops, and leaves you to figure what you have done to anger it.
So, the forward reference part would be a reference to something that does not yet exist. Forward in time perhaps..
In simple terms it means referencing (accessing a variable, calling a function) that is further down in the code file.
static int x=getY();
static int y=5;
static int getY() { return y; }
x's value is set to the result of getY()
getY() is called before y's value is set to 5
x's value is therefore 0 (default integer)
y's value is 5
public class AnyCode {
void print() {
System.out.println("Value of j - " + j); // legal
System.out.println("Value of i - " + i); // legal
}
// CASE - 1
int k = i; // illegal
int i;
// CASE - 2
int l = j; // legal
static int m = j; // illegal
static int j;
// CASE - 3
A aObj = bObj; // illegal
B bObj = new B();
public static void main(String[] args) {
/*
Note :- here anyCode act as a local variable and get space on stack
whereas the object it is referring to is present on heap. And you
cannot forward reference a local variable.
*/
anyCode.print(); // 'Cannot find symbol' error
AnyCode anyCode = new AnyCode();
}
}
class A {
}
class B {
}
*********Refer CASE - 1*********
Forward referencing instance variable is not allowed as compiler is not sure of the type of value we are forward referencing or it might even be possible that no such variable exist.
Consider an example :-
int a = b;
boolean b = false;
If forward referencing is allowed in above case then it might create a havoc.
int a = b; // What is b? is it a primitive variable or a value or a object reference
in the above example i have decided not to declare b and now if such assignment were allowed by java, then it will be a nightmare.
**********Refer CASE - 2*********
Static variables are loaded before instance variables and hence forward referencing static variables and assigning them to instance variable is perfectly fine