Basic Difference between static and non-static variables
class Student {
private int id;
private String name;
static String collegeName;
}
For every object of Students non-static
attributes id and name will be loaded into memory with its initial values (0 & null), id and name can be different for each object. But collegeName will only be loaded once, that's when class is loaded for execution. So for every object of Student
will have same college name. That's what is meant by static
.
Accessing static and non-static variables
class Student {
private int id;
private String name;
static String collegeName;
public static void main(String[] args) {
String s1 = Student.collgeName;
String s2 = collgeName;
Student student = new Student();
String s3 = student.name;
int id = student.id;
}
}
Static variables can be accessed directly by using their name or using the help of class name. When there is a static global variable and a local variable, the static one should be used along with the class name
public static void main(String[] args) {
String s1 = Student.collgeName;
String collgeName = "foo";
String output = collgeName;
}
Here output
will be having value "foo". Local variable is always having higher priority that global static variable and that's why String output = s1;
will give value for output as null
.
Inside a static block non-static
variables must be accessed with the help of reference variables (We have to create an object). Main method is static that's why we had to create object of Student
to access the values of id
and name
, otherwise it will give compile time error.
Blind rule regarding non-static blocks
Every non-static blocks will be using a default this
keyword representing current reference on which the block is invoked when a class level (static as well as non-static) variables are used. Sample java code
class Student {
private int id;
private String name;
static String collegeName;
void setData() {
id = 1;
name = "foo";
collegeName = "FooCollege";
}
public static void main(String[] args) {
Student student = new Student();
student.setData();
}
}
This is what happens when the same code is compiled to get the class file
class Student {
private int id;
private String name;
static String collegeName;
void setData() {
this.id = 1;
this.name = "foo";
this.collegeName = "FooCollege"; // which will be again as Student.collegeName
}
public static void main(String[] args) {
Student student = new Student();
student.setData();
}
}
Here this
representing the reference variable student
from main method. Represents the reference variable on which the block is invoked.
Coming to the question, main method creates a Test
object and on its reference method1()
is invoked. So inside method1
this is nothing but reference variable t
created in main method and t
is the local reference variable of the method. Now lets re-write the code in class file format
public void method1(int x) {
Test t = new Test();
this.x = 22; // or Test.x = 22;
y = 44; // or this.y = 44;
/*
Test object inside method1 and main method are in two different locations.
When we write this.y = 44; the y inside the main method object will be changed and not the one created inside method1.
*/
System.out.println("Test.x: " + Test.x);
System.out.println("t.x: " + t.x);
System.out.println("t.y: " + t.y); // means the y inside the object created inside method1
System.out.println("y: " + y); // means the y inside the object created inside main method
}
y
is not a static field. It's an instance field. So each Test instance has its own y. The method modifiesy
(i.e.this.y
), nott.y
. If you paint your car in black, your dad's car doesn't become black. Same here. – Territoriality