Here is my code:
class A { static A obj = new A(); static int num1; static int num2=0; private A() { num1++; num2++; } public static A getInstance() { return obj; } } public class Main{ public static void main(String[] arg) { A obj = A.getInstance(); System.out.println(obj.num1); System.out.println(obj.num2); } }
The output is 1 0
, but I can't understand.
Can somebody explain it to me?
Use the static modifier to declare a static member, which belongs to the type itself rather than to a specific object. The static modifier can be used to declare static classes. In classes, interfaces, and structs, you may add the static modifier to fields, methods, properties, operators, events, and constructors.
What does static mean? When you declare a variable or a method as static, it belongs to the class, rather than a specific instance. This means that only one instance of a static member exists, even if you create multiple objects of the class, or if you don't create any. It will be shared by all objects.
A static variable acts as a global variable and is shared among all the objects of the class. A non-static variables are specific to instance object in which they are created. Static variables occupies less space and memory allocation happens once. A non-static variable may occupy more space.
1 Answer. If you don't add the 'static' modifier in your main method definition, the compilation of the program will go through without any issues but when you'll try to execute it, a "NoSuchMethodError" error will be thrown.
In Java two phases take place: 1. Identification, 2. Execution
In identification phase all static variables are detected and initialized with default values.
So now the values are:A obj=null
num1=0
num2=0
The second phase, execution, starts from top to bottom. In Java, the execution starts from the first static members.
Here your first static variable is static A obj = new A();
, so first it will create the object of that variable and call the constructor, hence the value of num1
and num2
becomes 1
.
And then, again, static int num2=0;
will be executed, which makes num2 = 0;
.
Now, suppose your constructor is like this:
private A(){ num1++; num2++; System.out.println(obj.toString()); }
This will throw a NullPointerException
as obj
still has not got a reference of class A
.
What the static
modifier means when applied to a variable declaration is that the variable is a class variable rather than an instance variable. In other words ... there is only one num1
variable, and only one num2
variable.
(Aside: a static variable is like a global variable in some other languages, except that its name is not visible everywhere. Even if it is declared as a public static
, the unqualified name is only visible if it is declared in the current class or a superclass, or if it is imported using a static import. That's the distinction. A true global is visible without qualification anywhere.)
So when you refer to obj.num1
and obj.num2
, you are actually referring to the static variables whose real designations are A.num1
and A.num2
. And similarly, when the constructor increments num1
and num2
, it is incrementing the same variables (respectively).
The confusing wrinkle in your example is in the class initialization. A class is initialized by first default initializing all of the static variables, and then executing the declared static initializers (and static initializer blocks) in the order that they appear in the class. In this case, you have this:
static A obj = new A(); static int num1; static int num2=0;
It happens like this:
The statics start out with their default initial values; A.obj
is null
and A.num1
/ A.num2
are zero.
The first declaration (A.obj
) creates an instance of A()
, and the constructor for A
increments A.num1
and A.num2
. When the declaration completes, A.num1
and A.num2
are both 1
, and A.obj
refers to the newly constructed A
instance.
The second declaration (A.num1
) has no initializer, so A.num1
doesn't change.
The third declaration (A.num2
) has an initializer that assigns zero to A.num2
.
Thus, at the end of the class initialization, A.num1
is 1
and A.num2
is 0
... and that's what your print statements show.
This confusing behaviour is really down to the fact that you are creating an instance before the static initialization has completed, and that the constructor you are using depends on and modifies a static that is yet to be initialized. This something that you should avoid doing in real code.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With