The difference between static member variables and non-static member variables
Take the following example as an example
package cn.galc.test;public class Cat { /** * Static member variable*/ private static int sid = 0; private String name; int id; Cat(String name) { this.name = name; id = sid++; } public void info() { System.out.println("My Name is " + name + ",NO." + id); } public static void main(String[] args) { Cat.sid = 100; Cat mimi = new Cat("mimi"); Cat pipi = new Cat("pipi"); mimi.info(); pipi.info(); }}Understand the execution process of the entire program by drawing memory analysis diagrams
When executing the first sentence of the program: Cat.sid = 100;, the sid here is a static member variable. The static variable is stored in the data area (data seg), so first allocate a small space sid in the data area. After the sentence is executed, the sid contains a value of 100.
The memory layout diagram at this time is as follows:
Next, the program executes:
Cat mimi = new Cat(“mimi”);
Here, the constructor method Cat(String name) of the Cat class is called. The constructor method is defined as follows:
Cat (String name){ this.name = name; id=sid++; } When calling, first allocate a small piece of memory mm in the stack memory, which contains the address of the instance object of the Cat class in the heap memory. mm is the reference object of the Cat class object in the heap memory. This constructor declares a formal parameter variable of string type, so "mimi" is passed to the constructor as an actual parameter. Since the string constant is allocated and stored in the data area, there is an extra small piece of memory in the data area. Used to store the string "mimi". The memory distribution at this time is shown in the figure below:
When calling the constructor, first allocate a small space in the stack memory for the formal parameter name, and then pass the string "mimi" as an actual parameter to name. The string is also a reference type, except Except for those four and eight basic data types, all others are reference types, so it can be considered that a string is also an object. So this is equivalent to passing the reference of the "mimi" object to name, so now name points to "mimi". So the memory layout at this time is as shown below:
Next, execute the code in the constructor body:
this.name=name;
This here refers to the current object, which refers to the cat in the heap memory. Here, the value contained in the name in the stack is passed to the name attribute of the cat object in the heap memory, so at this time the value contained in the name can also be found in the string object "mimi" located in the data area. At this time, this name is also a reference object of the string object "mimi". Through its attribute value, the string object "mimi" located in the data area can be found. The memory distribution at this time is shown in the figure below:
Next, execute another line of code in the method body:
id=sid++;
Here, the value of sid is passed to id, so the value of id is 100. After the sid is passed, add 1. At this time, sid becomes 101. The memory layout at this time is shown in the figure below.
At this point, the constructor method is called, and all the memory space occupied by the local variables allocated to this constructor method will disappear, so the name memory located in the stack space disappears. The reference to the string object "mimi" in the data area in the stack memory also disappears. At this time, only the reference to the string object "mimi" in the heap memory remains. The memory layout at this time is as shown below:
Next execute:
Cat pipi = new Cat("pipi"); Here is the second call to the constructor method Cat(). The entire call process is the same as the first time. After the call is completed, the memory layout at this time is as shown in the figure below:
The last two lines of code are printed by calling the info() method. The printing results are as follows:
Through this program, we can see the role of this static member variable sid, which can be counted. Whenever a new cat comes out, give it a number. Let it add 1 by itself.
After the program is executed, the entire layout in the memory will be as shown in the figure above. Continues until the moment before the main method call is completed.
Here, the constructor method Cat(String name) is called to create two cats. First, two small spaces, mimi and pipi, are allocated in the stack memory, which contain the addresses where the two cats can be found. mimi and pipi correspond to the addresses in the heap memory. Two cat quotes. The construction method here declares a variable of string type. The string constant is allocated in the data area, so the passed strings mimi and pipi will be stored in the data area. Therefore, the data area is allocated two small blocks of memory to store the strings mimi and pipi, which contain the strings "mimi" and "pipi". Strings are also reference types. In addition to the four and eight basic data types, other All data types are reference types. So you can think of a string as an object.
Here are two new cats. Both cats have their own id and name attributes, so the id and name here are non-static member variables, that is, there is no static modification. So every time a new cat is created, this new cat has its own id and name, that is, the non-static member variables id and name have separate copies for each object. But for static member variables, there is only one copy. No matter how many objects are new, even if there are no new objects, the static member variables will retain one copy in the data area. Like the sid here, the sid is stored in the data area. No matter how many new cats are in the heap memory, there is only one copy of the sid, and only one copy is kept in the data area.
Static member variables belong to the entire class, they do not belong to a specific object. So how to access the value of this static member variable? First of all, any object can access this static value, and when accessing, it accesses the same memory. The second point is that you can access this static value even if there is no object. You can access this static value through "class name.static member variable name", so in the future you will see a certain class name plus "." followed by If there is one thing, then the following thing must be static, such as "System.out". Here, this out is accessed through the class name (System class) plus ".", so this out must be static.
If a class member is declared static, it can be accessed before any object of the class is created without having to reference any object. The most common example of a static member is main(). Because main() must be called when the program begins execution, it is declared static.
Variables declared static are essentially global variables. When an object is declared, a copy of the static variable is not generated, but all instance variables of the class share the same static variable. For example: declare a static variable count as the count of new class instances. Methods declared static have the following restrictions:
(1). They can only call other static methods.
(2) They can only access static data.
(3). They cannot reference this or super in any way.
If you need to initialize your static variables through calculation, you can declare a static block. The Static block is only executed once when the class is loaded. The example below shows
The class has a static method, some static variables, and a static initialization block: public class UserStatic { static int a = 3; static int b; static void meth(int x) { System.out.println("x = " + x); System.out.println("a = " + a); System.out.println("b = " + b); } static { System.out.println("Static block initialized."); b = a * 4; } public static void main(String args[]) { meth(42); } } Once the UseStatic class is loaded, all static statements are run. First, a is set to 3, then the static block is executed (printing a message), and finally, b is initialized to a*4 or 12. Then main() is called, main() calls meth(), passing the value 42 to x. The three println () statements refer to two static variables a and b, and the local variable x.
Note: It is illegal to reference any instance variables in a static method.
Here is the output of this program:
Static block initialized. x = 42 a = 3 b = 12
Static methods and variables can be used independently of any object outside the class in which they are defined. In this case, you only need to add the dot (.) operator after the class name. For example, if you wish to call a static method from outside the class, you can use the following general format:
classname.method()
Here, classname is the name of the class in which the static method is defined. As you can see, this format is similar to the format of calling non-static methods through object reference variables. A static variable can be accessed in the same format - the class name plus the dot operator. This is how Java implements a controlled version of global functions and global variables.
Summarize:
(1) Static members cannot be accessed by instances created by the class in which they are located.
(2) If the members without static modification are object members, they are owned by each object.
(3) Members modified with static are class members, which can be directly called by a class and are common to all objects.
Java Static: As a modifier, it can be used to modify variables, methods, and code blocks (but it must not modify classes).
(1) Modify variables:
A property shared by all objects of a class, also called a class variable. This is similar to global variables in C language. Class variables are initialized when the class is loaded and only initialized once. When any object in the program modifies a static variable, other objects will see the modified value. So class variables can be used as counters. In addition, Java Static variables can be accessed directly using the class name without requiring an object.
(2) Modification method:
A function common to all objects of a class is called a static method. Static methods can also be accessed directly using the class name, without requiring an object. Therefore, non-static variables and non-static methods cannot be directly accessed in static methods, and keywords such as this or super cannot appear in Static methods.
(3) Modify Java code blocks:
Use static to modify an independent code block in a class, which is called a static code block. Static code blocks are executed when the class is loaded for the first time, and only once. Static code blocks have no names, so they cannot be called explicitly, but are only called by the virtual machine when the class is loaded. It is mainly used to complete some initialization operations.
(4) Let’s talk about class loading:
When the JVM uses a class for the first time, it will go to the path specified by the classpath to find the bytecode file corresponding to the class, and read it into the JVM and save it. This process is called class loading.
It can be seen that whether it is a variable, method, or code block, as long as it is modified with static, it will be "ready" when the class is loaded, that is, it can be used or has been executed. All can be executed without objects. On the contrary, if there is no static, it must be accessed through the object.