Java, can't visualize output - java

I am super new to programming and I'm studying for a test and don't understand the output of a piece of code. I was hoping you could help me understand why the 4 is being printed at the end?
I threw the code in the Java visualizer site and I understand everything except why the line...
System.out.println(myScope.z); would print the number 4?
Any help is greatly appreciated!
public class ScopeTest {
int z;
public static void main(String[] args){
ScopeTest myScope = new ScopeTest();
int z = 6;
System.out.println(z);
myScope.doStuff();
System.out.println(z);
System.out.println(myScope.z);
}
void doStuff() {
int z = 5;
doStuff2();
System.out.println(z);
}
void doStuff2() {
z=4;
}
}

ScopeTest myScope = new ScopeTest(); initializes myScope.z to 0 (default value)
myScope.doStuff(); sets myScope.z to 5 and calls doStuff2()
doStuff2() sets myScope.z to 4.
The final result being 4. Key point is that the local z variables declared in the main and doStuff() methods have no bearing whatsoever on the z member variable declared in ScopeTest.

Stepping through code one line at a time is a good exercise to figure out what it is doing. You should do this with paper and pencil as well as with a debugger. So let's step through your code one line at a time in the order of execution. After each line of code, I'll explain what it does.
ScopeTest myScope = new ScopeTest();
Create a local reference variable named myScope and initialize it to an object.
int z = 6;
Create a local int variable named z and initialize it to 6.
System.out.println(z);
Print the value of the local variable z.
myScope.doStuff();
Call doStuff() on the myScope object.
int z = 5;
Create a local variable z in doStuff() and initialize it to 5.
doStuff2();
Call doStuff2()
z=4;
Set the member field named z to the value 4. And then return control back to doStuff().
System.out.println(z);
Print out the value of the local variable z. And then return control back to main().
System.out.println(z);
Print out the value of the local variable z. (Remember we are back in main() now.
System.out.println(myScope.z);
Finally, print out the member field z. (Remember its value was set back in doStuff2(). This value is remembered because this z is a member variable.)

This is the Flow:
myScope.doStuff() --> 1. z=5 2. doStuff2() --> z=4

You are calling dostuff() in main() method, there you have initialized z=5 which is its local variable z and not class variable z. so then you are calling dostuff2() in which you are actually modifying class variable z=4. That is why it is printing z=4 in last syestem.out.println(z). Hope this will help you understanding output.

because In your code z declared in the first line, is instance member (this context).
so when ever doStuff2() is called this.z is set to 4.
//effectively
void doStuff2() {
this.z=4;
}
the variables int z declared inside the methods main and doStuff() are in local context.
and here, it only matters when the value of z in this context is set finally (which is inside doStuff2()).
Thus,
System.out.println(z); >> prints value of local variable z declared in main
System.out.println(myScope.z); >> prints the value of instance (of ScopeTest which is myscope here) member z

Related

Java instance variables initialization with method

I am a little bit confused about the following piece of code:
public class Test{
int x = giveH();
int h = 29;
public int giveH(){
return h;
}
public static void main(String args[])
{
Test t = new Test();
System.out.print(t.x + " ");
System.out.print(t.h);
}
}
The output here is 0 29, but I thought that this has to be a compiler error, because the variable h should have not been initialized when it comes to the method giveH(). So, does the compilation go through the lines from top to bottom? Why is this working? Why is the value of x 0 and not 29?
The default value of int is 0 (see here). Because you initialize x before h, giveH will return the default value for a int (eg 0).
If you switch the order like this
int h = 29;
int x = giveH();
the output will be
29 29
Compilation in Java doesn't need the method to be declared before it is used. The Java tutorial goes into a bit more detail on initialization.
Here's a way to think about it: the compiler will make a note to look for a method called giveH somewhere in scope, and it will only error if it leaves the scope and doesn't find it. Once it gets to the giveH declaration then the note is resolved and everyone is happy.
Also, the variable initialization for instance variables in Java is moved to the beginning of the constructor. You can think of the lines above being split into two parts, with the declaration for x and h above, and the assignment inside the constructor.
The order of declaration does matter in this case. When the variable x is initialized, h has the default value of 0, so giveH() will return that default value. After that, the variable h is given the value 29.
You can also look at the Java Language Specification sections on Field Initialization and Forward References During Field Initialization.
#Maloubobola has provided the correct answer, but since you don't seem to fully understand yet, let me try to elaborate.
When Test is created, it runs the variable initialization (x = giveH(), h= 29) once. Your misunderstanding may be that variable x is always determined by giveH(), whereas it only determines it's value when x is initialized.
That's why the order of the statements is crucial here; x is initialized before h, and therefore h is 0 when giveH() is called at x's initialization.
It's bad practice to use a method in the field initializer. You can fix this by making h final. Then it will be initialized when the class is loaded.
import java.util.ArrayList;
public class Test {
int x = giveH();
final int h=29;
final public int giveH(){
return h;
}
public static void main(String args[]) {
Test t = new Test();
System.out.print(t.x + " ");
System.out.print(t.h);
}
}
If we do not initialize the value for non static variables like x in this program JVM will provide default value zero for class level non static variables.
Once declared, all the array elements store their default values.
Elements in an array that store objects default to null.
Elements of an array that store primitive data types store:
0 for integer types (byte, short, int,long);
0.0 for decimal types (float and double);
false for boolean;
\u0000 for char data.
Actauls values will come only when we give initialize them

Java - printing a variable that was declared inside an if statement

So I'm trying to declare an integer variable inside an if/else statement, and print it out, outside of it. Something like this:
int x;
int a = 1;
if (a == 1)
{
int x = 5;
}
System.out.println(x);
This is just an example of what I'm trying to do, as I don't have the actual code with me, and i don't want to redo it all over. Although it shouldn't matter really, as the example is exactly what i need, only with different variable values and names (but it's still an integer). At first i just declared and initialised the variable inside the if/else statement, but then I was told I need to declare it outside the statement... So I did that, then initialised it within the statement, and then proceeded to call on it later on. However I'm still getting an error, either it says the variable hasn't been initialised, or if I assign a value to it (x) then update it inside the statement, the error i get is that it has already been declared. Any help would be appreciated, thanks.
Yes. Local variables needs to be initialize before they use. Where as instance variables initialize to default values if you didn't initialize them before use.
If you are curious about the reason? click here to know
Coming back to your question again,
Because consider the below scenario
Follow comments.
int x; // declared with no value
int a = 0;
if (a == 1) // this is false
{
x = 5; // this never executed
}
System.out.println(x); // what you are expecting to print here ?
Hence you need to initialize with a value. For ex : initialize it with zero and change it later on based on a condition
int x=0;
int a = 1;
if (a == 1)
{
x = 5;
}
System.out.println(x);
Simply assign the int x = 0 before your if-statement, then instead of redeclaring x as an integer equal to 5, set x equal to 5 inside your if statement.
The point is that you declared x above. So remove int before x inside the if-statement. Then it works.
int x;
int a = 1;
if (a == 1) {
x = 5;
}
System.out.println(x);
Implicitly an integer is initiated with 0. If you want to be sure just write
int x = 0;
your code here
int x = -1;
int a = 1;
if (a == 1)
{ // here begins inner 'area' for declared variables
x = 5;
}// and here ends
System.out.println(x);
OK, my bad! I wanted him to wonder why and try some other ways of writting it and letting him get 'hit' by IDE errors.
So Mr. Unknown as far as you declare variable 'inside' if statement it is visible only across that statement! So basicly if You want to do something with variable inside if statement, and have results outside of it, You need to declare it outside the statement making it having wider range of accessibility! If You have any questions don't hesitate to ask ;)
P.S. Watch out for re-declaring variable with the same name like You tried to do here, it's nasty bug to find =)
Thank you all for the answers, I realized I made 2 minor mistakes that didnt allow it to work, I (in most attempts) didn't declare a value for x before the if statement, and I had 'int' in front of x inside the if statement, which caused the re-deceleration error. So yea, thank you for the quick answers :)

Trying to understand static variables. Why does 6 get printed in the 2nd to last print statement?

My understanding of a static field is that its last assignment is what that field's value will be wherever it is found in the class. However, my understanding clearly isn't solid because I expected the 2nd to last print statement to print 30, not 6. Please help me understand why it printed 6.
public class Whatever
{
static int x = 2;
static int z;
public Whatever()
{
z = x*3;
}
public static void main(String[] args)
{
Whatever foo = new Whatever();
System.out.println(foo.z); //prints 6
Whatever.x = 10;
System.out.println(foo.x); // prints 10
System.out.println(foo.z); // prints 6 WHY?!?!
Whatever bar = new Whatever();
System.out.println(bar.z); // prints 30 as expected
}
}
Whatever.x = 10; // This only sets your "x" to 10.
System.out.println(foo.x); // prints 10
System.out.println(foo.z); // prints 6 - because x is 10, but z is still 6
Whatever bar = new Whatever(); // Now z = x*3 is called and z becomes 30.
System.out.println(bar.z);
Its just that the statement in your constructor z=x*3 is not called always when you set some new value for x.
To understand this, you need to know what static means. In Java, static variables are at the Class level. Another way to think about it is, all instances of that class see the same thing. So, in your example, no matter how many Whatever objects you create (even if you create NONE!) there is only one x and only one z.
So, let's walk through it...
// Executes z = x*3, setting z to 6 (as you expect)
Whatever foo = new Whatever();
System.out.println(foo.z); //prints 6
// Sets x to 10 (remember, x is static, you only have one of them!)
Whatever.x = 10;
System.out.println(foo.x); // prints 10
// Because since the last time you've created a Whatever,
// nothing has changed z!
System.out.println(foo.z); // prints 6 WHY?!?!
// Now you've created a new Whatever, and z = x*3 gets executed
// in the constructor again
Whatever bar = new Whatever();
System.out.println(bar.z); // prints 30 as expected
I hope that helps!
Static variables are called so because they are located statically in memory. When you instantiate your foo object, the constructor multiplies x by 3, and assigns the result to z.
When your main method begins,
x = 2 and z has not been instantiated.
When foo is instantiated,
x = 2 and z = x * 3. Since x is now 2, z = 2 *3 = 6
You then assign x to be 10.
Z is STILL 6 because z is not assigned until your bar object is called.
If you expect is to be 30 at that point in time, you would have to call z = x * 3 again.
Changing the variable x will not automatically change the value of z
Take a look HERE
When a number of objects are created from the same class blueprint, they each have their own distinct copies of instance variables. (...)
Sometimes, you want to have variables that are common to all objects. This is accomplished with the static modifier. Fields that have the static modifier in their declaration are called static fields or class variables.
Because z = x*3 is in the constructor method.
Constructor method is call when you write
Whatever foo = new Whatever();
so when u assign
Whatever.x = 10;
constructor method was not call again
Lets c what happens line by line
public static void main(String[] args)
{
Whatever foo = new Whatever(); // new is a operator to create an object. when the object is created it will try to call constructor . No constructor, it will fail to create the object. so Now the constructor is called. It calculates x*3 and puts the value to z.
System.out.println(foo.z); //prints 6. Here value of z is read printed. This is not method invocation. This is just reading value of z
Whatever.x = 10; // This is an assignment statement. It just puts the value into x
System.out.println(foo.x); // prints 10 Just the values read
System.out.println(foo.z); // prints 6 WHY?!?! // Here to value of z is read. If you see. now alteration of value is done on z.
Whatever bar = new Whatever(); // this recalculates and puts the value on to z. That is why you are seeing change when you print z after this statement.
System.out.println(bar.z); // prints 30 as expected
System.out.println(foo.z); // Should also print 30 now. thats what static does
}
hope this helps
Static variables will have only one instance across different instances.
Here
at first
Z was 2
When you call
public Whatever()
Z was changed to 6
after that you have changed X
but that had no impact on Z
so the value is 6
Thanks

Changing a variable though a module in a loop (java)

So I am trying to write a simple program for my Java class and I have asked the teacher for help however, this is a distance learning class and am not getting much help from that direction. So here I am.
The problem we have been asked to solve is to create a program that will
(1) ask the user for a number ,
(2) find the sum of all user defined numbers ,
(3) find the average of these numbers ,
(4) then out put them back to the user.
I use the numbers not only to line through things I have finished but because they must be separate modules to be called.
How can i get the userNum variable to update durring the while statments. Currently they are not. OR is there a simpler way to do this that im overlooking. Any help is greatly appreciated. Thank you.
public class P2 {
public static void main(String[] args) {
int userNumCount = 1;
double userNum = input();
double userSum = sum(userNum);
double userAverage = average(userSum, userNumCount);
sum(userNum);
while (userNum != 0 && sum(userNum) <= 100){
++userNumCount;
output(userSum, userAverage);
input();
sum(userNum);
average(userSum, userNumCount);
}//end else
while (userNum != 0 && sum(userNum) >=100){
++userNumCount;
JOptionPane.showMessageDialog (null, "Warning, your sum is currently over 100!!!!!");
output(sum(userNum), userAverage);
input();
sum(userNum);
average(userSum, userNumCount);
}//end else
if (input() == 0){
output(userSum, userAverage);
JOptionPane.showMessageDialog (null, "Thank you for using this program have a nice day.");
}//end else if
}//end main module
public static double input(){
String userNumString;
userNumString = JOptionPane.showInputDialog("Please enter your number or input 0 to end the program.");
double userInput = Double.parseDouble (userNumString);
return userInput;
}//end input module
public static double sum(double userNum){
double userSum =+userNum;
return userSum;
}//end sum module
public static double average (double userSum, int userNumCount){
double userAverage = userSum/userNumCount;
return userAverage;
}//end average module
public static void output (double userSum, double userAverage){
JOptionPane.showMessageDialog (null, "The sum of the numbers input so far is: " + userSum + ". And the Average is " + userAverage + "." );
}//end output module
}//end class
All of the values returned from methods in your main are just returning their values to nothing. When you pass variables to a function, they are passed by value. For example:
public void main(String args[]){
int f = 5;
doSomething(f);
System.out.println(f);
}
public int doSomething(int i){
i+=1;
return i;
}
The value returned by doSomething is 6, but the program outputs 5. When you call a function the int i is recreated independently of f. As of now, your program is just throwing those values away and keeping the old ones.
Also you have the variables in main called userSum, and userAverage, and in sum and average you redefine these in a different scope. When code flow comes into sum and average it creates new variables for that method. If you want these values to be the same you need to make them static, by defining them outside of your main method and declaring them static.
I think the problem you might be struggling with is scope. Pretty much every time you have an opening bracket the program changes scope. When a block is closed (when there is a closing bracket}, the scope of the variables ends, ie. they don't exist anymore. For example:
class someClass
{
//Block 0
static int staticNum = 0;
public static main(String args[])
{
//Block 1
int level1 = 0;
if(true)
{
//Block 2
int level2 = 0;
} else {
//Block 3
level1++; //ok because the level1 is accessible from here
staticNum++; //ok because staticNum is static
}
//resume block 1
level2++; //not ok because level2 was in a different scope
doSomething(level1)
}
public static void doSomething(int i){
//Block 5
int level1 = 0; //different than the one in the main method
i++; //ok but once execution leaves i wont exist anymore
staticNum++; //ok because staticNum is static and exists in the class's scope
level1++; //not ok because level1 is not defined for this scope
}
}
While execution is in a block, it can access any variable in blocks 'above' it in nesting level. Looking at the above, in Block 2 and 3 you can access anything in block 1 or block 0. Block 3 doesn't have access to the variables in block 2 because they are out of scope of one another, because when a block closes all variables instantiated in that block are freed. Block 5 has a completely different scope than block 1,2 and 3.
Block 0 is special because it is associated with the class. Anything outside of method bodies declared static are class wide variables, as in you can access it where ever you have access to the class. You would use something like ClassName.staticNum to access it in another class. Also when you access it inside of the class, any methods that you use the static values in need to be declared static as well.
Anything not declared static in the class body is an instance variable. It is associated with an instances of the class, these instances called objects. A class defines the template of an object. For example, lets say we have two objects of type Computer. The class Computer defines what variables each individual computer has(instance variables), and what variables every computer shares(static variables). So if I have Computer A with instance variables mouse and keyboard, it is completely different from another Computer B instance variables mouse and keyboard, but they can share a static variable called Computer.innernette.
This is incorrect.
public static double sum(double userNum){
double userSum =+userNum;
return userSum;
}
In a basic pseudo-language this is happening each time this method is called
receive userNum
create userSum
set userSum = 0
add userNum to userSum
give userSum
each time the method will return the value it is given, not the running total I think you are expecting.
If you have two variables declared with the same name, they are still different. What you want to do is refer to the same variable, to do this you need to have the references in the scope where the variable is declared.
to get the running total
public class P2 {
public static double userSum = 0;
//because this is a public member it's scope is global i.e. you can refer to it anywhere.
...
public static void main(String[] args) {
...
/* do not declare userSum here.
if you do any reference to userSum will use the local variable
not the global variable.
double userSum = 0; <-- declare local variable it's scope is until the
end of this method nothing outside the method
can see it but you can pass it as a parameter
userSum = 1; <-- local variable is set to 1
P2.userSum = 2; <-- local variable is set to 1 global is set to 2
*/
input();// for this the input method is called and returns a value,
// but you haven't said to put it anywhere so java will throw it away
// all that effort for nothing.
userNum = input(); // in this case it will put the new value in userNum.
}
public static double sum(double userNum){
userSum =+userNum; // do not declare userSum use it from the class context
return userSum;
}
...
}
for further reference scope

Confused over initialisation of instance variables

I'm studying up for the SCJP exam, upon doing some mock tests I came across this one :
It asks what is the output of the following :
class TestClass
{
int i = getInt();
int k = 20;
public int getInt() { return k+1; }
public static void main(String[] args)
{
TestClass t = new TestClass();
System.out.println(t.i+" "+t.k);
}
}
I thought it would be 21 20, since t.i would invoke getInt, which then increments k to make 21.
However, the answer is 1 20. I don't understand why it would be 1, can anyone shed some light on this?
The variables are initialized from top to bottom.
This is what happens:
Initially both i and k have the (default) value 0.
The value computed by getInt() (which at the time is 0 + 1) is assigned to i
20 is assigned to k
1 20 is printed.
Good reading:
The Java™ Tutorials: Initializing Fields
jvm will follows like this,
1.identification for non-static members from top to bottom
2.executing non-static variables and blocks from top to bottom
3.executing the constructor......
in the first step jvm will provide default values..on that time variables in readindirectly write only state..

Categories

Resources