Static variables in java - java

I have scenario like this
public class Test{
static int a;
int b;
public static void main(String[] args){
Test t1 = new Test();
Test t2 = new Test();
}
}
What will be the variables in object t1 and object t2?
As per my understanding since variable a is a static variable it will be both in object 1 and object 2.
And b will be created separate copy for both the objects.
But when I assign a value to variable b ie(int b=1) and call it like System.out.println(t1.b), System.out.println(t2.b)
Instead of getting an error I am getting 1 as output from both the objects.
Why is that?

As per my understanding since variable a is static variable it will be both in object 1 and object 2.
No. It's not in either object. It exists without reference to any particular instance at all. Although Java allows you to refer to it "via" a reference, e.g. int x = t1.a; you shouldn't do so. You should instead refer to it via the class name (test.a in your case - although you should also start following Java naming conventions) to make it clear that it's static.
And b will be created separate copy for both the objects.
Yes.
But when I assign a value to variable b ie(int b=1) and call it like System.out.println(t1.b), System.out.println(t2.b) Instead of getting an error I am getting 1 as output from both the objects.
Well that's because you've basically given it an initial value to assign for each new object. That's entirely reasonable. There are still two independent variables:
t1.b = 2;
t2.b = 3;
System.out.println(t1.b); // Prints 2
System.out.println(t2.b); // Prints 3

Static variables are class members that are shared among all objects. There is only one copy of them in main memory. Static variables are created at run time on Heap area.
In case of yours...
int b = 1;
it's an assignment at class level, making 1 the default value for variable b(In normal case default value is 0). hence when you print it, its gives you the ans as 1 not error.
int b = 1; //initialized b to 1 for all obj of class Test
System.out.println(t1.b); // Prints 1
System.out.println(t2.b); // Prints 1

No, a static variable is not an instance variable but a class variable.
That's, every instance of this class shares the same reference of those variables.
Take a look at Understanding Class Members

Here a is static variable and b is instance or non-static variable.
For static variable, only one copy is created for all objects, where as for instance variable, one copy is created for each object.
Here when b=1, for every object of that Test class, one copy is created and it can access it through its object name. So output will be 1.

Of course that is exactly what it should output.
If you assign say,
int b=1;
that assignment is at class level, making 1 the default value for variable b.
However, if you assign like this:
t1.b=1;
that will assign 1 to only the copy of variable b in object t1.
Try it.

static variables are class variables. static variable are stored in static memory.
static variables are created to access inside main() method.
The static variables can be accessed by their class name, if they are present in outside class.
class sv {
static String name = "abc";
}
public class staticvariable {
static int t;
public static void main(String[] args) {
System.out.println("static variable is - "+t);
System.out.println(sv.name);
t=100;
System.out.println(t);
}
}

Related

In Java are object attributes passed by reference to other classes

If I have a class like such:
public class First {
int x = 1;
}
and a second class:
class Main {
public static void main(string args[]) {
First someObject = new First();
someObject.x = 2;
}
}
is only someObject.x equal to 2 or would any object of class First being created afterwards be initialized with it's x attribute being equal to 2. If not, how would one change the default value of x for any object being made of class First?
First of all, you need to read about what "pass by reference" really means. (For example, here.) Passing semantics refer to what happens to arguments in a procedure/method/subroutine/function call. In your example, there is no "passing" going on at all when you are assigning to the x field.
So your
In Java are object attributes passed by reference to other classes
is a meaningless and/or irrelevant question. (But the plain answer is that Java does not support "pass by reference". Period.)
As for what I think you are trying to ask, lets start with some facts:
The Field class declares x as an instance field.
Each instance of First has its own "copy" of the x field.
The x field is part of one and only one instance. It is not shared with any other First instance.
This is irrespective of the declared type of x ... modulo that a field whose declared type is a reference type will contain a reference to an object rather than the object itself. (But int is not a reference type.)
The new First() expression creates a new instance of the First class that is distinct from all other (past, present or future) instances of First and returns its reference.
So, in this code:
First f1 = new First();
First f2 = new First();
f1.x = 2;
System.out.println(f2.x); // prints 1.
We have two instances of First that f1 and f2 refer to (point at) distinct First instances. If you change the x field of one instance does not change the x field of the other intance. They are different fields.
However, if you had declared x as static in First, then x is no longer a distinct field for each First instance. It is now a shared by all instances of First.
As an addendum, how would one change the default value of x in the First class such that any new instance made afterwards would have a difference value of x to start?
Firstly int x = 1; in First is not defining a "default" value in the sense that Java uses that term. It is actually an initialization. (A default value is what you see if you DON'T have an initialization.)
If you wanted to implement application specific default value that is common to all instances of First and that can be changed retrospectively, you need to implement it in Java code. Maybe something like this:
public class First {
static int defaultX = 1;
private int x;
private boolean xSet = false;
public int getX() {
return xSet ? x : defaultX;
}
public void setX(int x) {
this.x = x;
this.xSet = true;
}
}
Note that in order to implement the defaulting behavior we want, we have to hide the x field (make it private) and implement the desired behavior in the getter and setter methods.

Constructors: do Instance variables store separate values for objects?

Suppose we initialize the instance variables with some values, and then again initialize them inside a constructor with some other values, so does that mean that variables will hold separate values for objects regardless of what we initialized them to outside the constructor? For example:
class A {
int a = 2;
A(int p) {
a = p;
}
public void Foo(String args[]) {
A obj = new A(5);
}
}
In the above code, do 'a' and 'obj.a' hold seperate values?
In the above code, do 'a' and 'obj.a' hold seperate values?
Yes. obj.a holds the value 5, while a holds the value "there isn't any such variable and there's no meaningful answer to what its value is."
There is no a by itself, only the value of a associated with a particular instance of the class A.

Strange array behaviour in java. An array with a single int behaves differently than the same program with the int not in an array

Why is there a difference between the following two programs A & B. Shouldn't they run identical? For some reason the changer in the case of the array is changing the original value of the input array.
Program A:
public static void changer(int tester) {
tester = tester*2;
}
public static void main() {
int value = 1;
out.println(value);
changer(value);
out.println(value);
}
which gives me the output:
1
1
Program B:
public static void changer(int[] tester) {
tester[0] = tester[0]*2;
}
public static void main(){
int[] value = {1};
out.println(value[0]);
changer(value);
out.println(value[0]);
}
which gives me the output:
1
2
Changing a value in a called method does not change the value in the calling method. In Program B, you're not changing the array, you're changing a value inside the array, and that is visible in the calling method.
In your first example, you passed an int (tester) to the function, and then assigned a new value to it. Since java is pass-by-value, assignment has not effect outside of the callee scope, and so the original value was not changed in the call site.
In the second example, you passed an int array to the function, and then you did not assign to it, but modeified its content, by assigning to a specific cell inside of it, so the value was changed in the call site as well.
Passing primitive data type ( i.e int, double, long, float, ....) to a function or method will be " PASSED BY VALUE". In program A, the argument passed to method is a primitive data (int), so you just passed a copy of the origin value. Any change to it, will not affect the origin number.
But passing Reference/Object data type (i.e, Array, ArrayList, HashMap,...) to a function will be " PASSED OBJECT BY VALUE," which means the method is given copy of the reference to the object. So any change to it, will change the origin reference. In program B, you passed a reference copy of an array. That is why it has been modified.
When arrays work like pointers. When you use
tester[0] = tester[0]*2;
You are basically telling compiler to update element in memory on location tester[0]
This question had been asked so many times. Java passes everything by value and this is especially true for primitive such as int.
When you pass an int argument, you are passing in the value, not the reference of the variable.
public static void main(String[] args){
int value= 5;
changer(val);
}
public static void changer (int tester){
//A variable call tester holding the value of 5
}
A local variable call tester with value of 5 will be created, because you passed in a value of 5. Variable val itself was not passed in.
Any changes done within the method is merely changing the local variable tester.
This explains why the value of val remains unchanged.
When you pass in an array, it still passes by value, but the value does not contain all the values of individual array element. It will be very inefficient to copy the entire array's value for every method invocation. The value holds the reference of the array. Thus, tester now holds the reference of the val.
public static void main(String[] args){
int[] val= 5;
changer(val);
}
public static void changer (int[] tester){
//A variable call tester holding the reference of val array.
}
Since tester is now pointing at the original array: val. Anything you changed in the method will affect the original array.

Method passing by value in Java

First of all, I understand what's so called passing by value in Java.
Also I understand, when you pass an object or an array, it is the array's address that is passed into the method. So modifying the array variable inside the method will affect the outside array variable.
For example,
private void change(int[] a) {
a[0] = 1234;
}
public static void main(String[] args) {
int[] a = new int[2]{1,2};
change(a);
System.out.println(a[0]);
}
The output will be 1234, because the a inside change is actually the array outside.
What I don't understand is the following code:
private void change(int[] a) {
a = new int[3]{1234, 4, 5};
}
public static void main(String[] args) {
int[] a = new int[2]{1,2};
change(a);
System.out.println(a[0]);
}
Why the output is 1, not 1234?
The inside a was the same thing as outside a, right? I also modify the inside a just like the example above did, why two different output?
This is not the same. In your second example, you are changing the local reference a to refer to a completely new array, not changing the existing array. But this does not change the a in main to refer to the new array; it still refers to the old array, so 1 is printed.
If you wanted to re-assign a completely new array to the a in main using a method, then return the new array from change and assign that to a in main.
Let's inspect your function:
private void change(int[] a) {
a = new int[3]{1234, 4, 5};
}
As you stated in your question, a is a reference to an array. If you use it to modify the array (e.g., a[0]=1234), you will be changing the same array that was passed in to the function.
However, if you change the reference itself, a will no longer be pointing to the original array, and changes to it will not affect the original.
This is exactly because the reference is passed by value. We'll represent object pointers with 5-digit numbers like 12345. The process is as follows:
We create an int[]{1,2}, at memory location, say 10000. We assign a the value 10000. a is on the stack frame corresponding to main.
We pass the value 10000 to change.
change executes:
change creates a new array at location 20000 and sets the value of a on its stack frame to 20000. This does not affect the main stack frame.
change returns (void).
We deference the untouched pointer to the original array in order to print the zeroth element, 1.
Note that by the time change returns, we have no live references left to {1234, 4, 5}.
In Java all variables are references to objects.
When you pass a variable into an array, you pass the reference to the object. If you modify the object then the calling method - which also has a variable that refers to the same object - sees the change.
When you write "a = new int..." you are changing the value of the variable a to point to a different object. It is no longer referring to the same object as the one in the method that called it. So the calling method and the called method see different things.
When you pass a parameter by value, it basically means that it's copied from a method's point of view. So, you have a reference a to an array, and when you pass it to some method, inside that method you have another reference, also named a to the same array. Now, when you assign a new value to that reference (a = new int[]...) you are only modifying the local a variable to point to a new array.
The answer has as much to do with passing by reference or value as it does with which variables are in scope when you attempt to make the change.
When you pass "a," or any variable to a method, you pass the value of that variable - in other words a copy of what it represents- and not the actual variable itself. For example:
public static void main(String[] args){
int a = 3;
addTwo(a);
System.out.println(a);
}
private void addTwo(int a){
a += 2;
}
In the above example the value 3 is passed to addTwo. The variable "a" in the main method is outside of its scope (i.e. it is localized to the main method) so the addTwo method acts only on the copy of "a," the value 3, and not the variable. The variable "a" remains unchanged. When the method completes the value of a is discarded and the original "a" in the main method remains unchanged.
This is the same thing that is happening in your case. It does not matter that you use the same name for two variables. The variable in your main method will not be changed.

why i can interchange field values inside a class using class reference but can't interchange the references themselves

Here is the code of the class i have written
class Demo
{
int x,y;
Demo(int a,int b){x=a;y=b;}
public void swap(Demo ref) // interchanges field values of x and y
{
int temp;
temp=ref.x;
ref.x=ref.y;
ref.y=temp;
}
public void change(Demo ref1,Demo ref2) // supposed to interchange to class variables of Demo class
{
Demo temp = ref1;
ref1 = ref2;
ref2 = temp;
}
}
swap method works fine i.e. interchange values of x and y.
Now, I have two questions here:
how the swap method is able to change the actual data passed to it? (I have read that their is no pass by reference in Java.)
why change method does not interchange class references?
Pass-by-value in Java is somewhat interesting. You're passing a reference to an object on the heap by value. So, by dereferencing/accessing ref you're accessing an existing object on the heap. That object's fields are changed, and any other references to that Demo instance will reflect these changed when dereferenced(as it's the same object).
Because references are passed by value, calling change(myDemo1, myDemo2) passes the values of the myDemo1 and myDemo2 references. We're not passing in a reference to the myDemo1 reference. Switching around the values won't affect them outside the method.
Let's just say that for simplification's sake the references are valued 12345 and 23456. For the first, we pass in a reference to 12345, and we then change things with that object. Any other dereferencing of 12345 will reflect those changes.
Now, let's try the following:
public static void main(String... args){
Demo d1,d2;
d1=new Demo(1,2); //VALUE of d1 is 12345, and deferencing d1 will get us a demo object at 12345 with 1 and 2.
d2=new Demo(9,8); //VALUE of d2 is 23456. Deference it, get a demo with 9 and 8.
change(d1,d2); //d1 and d2 are passed by VALUE. `change()` gets its own copy of d1 and d2 to play with.
}

Categories

Resources