Four uses of Static keyword in Java
1. Modify member variables
In our daily use, the most common function of static is to modify class properties and methods to make them become class member properties and methods. We usually call members modified with static as class members or static members. This sentence sounds a little strange. In fact, this is relative to object properties and methods. Look at the example below
public class Person { String name; int age; public String toString() { return "Name:" + name + ", Age:" + age; } public static void main(String[] args) { Person p1 = new Person(); p1.name = "zhangsan"; p1.age = 10; Person p2 = new Person(); p2.name = "lisi"; p2.age = 12; System.out.println(p1); System.out.println(p2); } }
Output results:
We are very familiar with the above code. Each object constructed according to Person exists independently and saves its own independent member variables, which will not affect each other. Their schematic diagram in memory is as follows:
As can be seen from the above figure, the objects referenced by p1 and p2 variables are stored in different addresses of the heap area in memory, so they will not interfere with each other. But in fact, we have omitted some important information. I believe everyone will think that the member properties of objects are here and saved by each object. What about their methods? In fact, no matter how many objects a class creates, their methods are the same:
From the above figure, we can see that the methods of the two Person objects actually point to the same method definition. This method is defined as an invariant area (divided by the jvm) in memory, which we temporarily call static storage. This storage area not only stores the definitions of methods, but also stores various definitions. When we generate objects through new, we will create objects according to the definitions of the classes defined here. Multiple objects only correspond to the same method. Here is a convincing reason for us, that is, no matter how many objects, their methods are always the same. Although the final output will be different, the methods will always operate according to our expected results, that is, different objects call the same method, and the results will be different.
We know that the static keyword can modify member variables and methods to make them belong to the class rather than the object. For example, if we modify the age attribute of Person with static, what will be the result? Take the following example:
public class Person { String name; static int age; /* The rest of the code remains unchanged */ }
The output result is:
We found that the result changed a little. When assigning a value to the age attribute of p2, it interfered with the age attribute of p1. Why? Let's take a look at their schematic in memory:
We found that after adding the static keyword to the age attribute, the Person object no longer has the age attribute. The age attribute will be uniformly managed by the Person class, that is, multiple Person objects will only correspond to one age attribute. If an object changes the age attribute, other objects will be affected. We can see that the age and toString() methods at this time are managed by the class.
Although we see that static allows objects to share attributes, we rarely use it in practice and do not recommend it. This makes the property difficult to control because it can be changed anywhere. If we want to share properties, we usually use other methods
public class Person { private static int count = 0; int id; String name; int age; public Person() { id = ++count; } public String toString() { return "Id:" + id + ", Name:" + name + ", Age:" + age; } public static void main(String[] args) { Person p1 = new Person(); p1.name = "zhangsan"; p1.age = 10; Person p2 = new Person(); p2.name = "lisi"; p2.age = 12; System.out.println(p1); System.out.println(p2); } }
The output result is
The above code plays the role of creating a unique id for the Person object and recording the total number. Count is modified by static and is a member attribute of the Person class. Each time a Person object is created, the attribute will increase by 1 and then be assigned to the id attribute of the object. In this way, the count attribute records the total number of Person objects created. Because count uses the private modification, So you can't change it from outside the class.
2. Methods of modifying members
Another function of static is to modify member methods. Compared with modifying member attributes, modifying Member methods does not have much change in data storage, because we can see from the above that methods are originally stored in the class definition. The most important function of static modified member method is to use "class name. Method name" to operate the method, avoiding the cumbersome and resource consumption of new objects first. We may often see its use in the help class:
public class PrintHelper { public static void print(Object o){ System.out.println(o); } public static void main(String[] args) { PrintHelper.print("Hello world"); } }
The above is an example (not very practical yet), but we can see its role, which makes the static modified method become the method of the class. It can be used conveniently through "class name. Method name", which is equivalent to defining a global function (just import the package where the class is located). However, it also has limitations. In a static modified class, non static modified member variables and methods cannot be used, which is easy to understand, because the static modified method belongs to the class. If you directly use the member variables of the object, it will be at a loss (I don't know which object attribute to use).
3. Static block
When explaining the third usage of static keyword, it is necessary to re sort out the initialization process of an object. Take the following code as an example:
class Book{ public Book(String msg) { System.out.println(msg); } } public class Person { Book book1 = new Book("book1 Member variable initialization"); static Book book2 = new Book("static member book2 Member variable initialization"); public Person(String msg) { System.out.println(msg); } Book book3 = new Book("book3 Member variable initialization"); static Book book4 = new Book("static member book4 Member variable initialization"); public static void main(String[] args) { Person p1 = new Person("p1 initialization"); } }
The output result is:
In the above example, four Book member variables are combined in the person class, two are ordinary members and two are static modified class members. We can see that when we new a Person object, the static modified member variable is initialized first, followed by an ordinary member, and finally calls the Person class construction method to complete the initialization. In other words, when creating an object, members decorated with static will be initialized first, and we can also see that if there are multiple members decorated with static, they will be initialized according to their sequence.
In fact, members decorated with static can be initialized earlier. See the following example:
class Book{ public Book(String msg) { System.out.println(msg); } } public class Person { Book book1 = new Book("book1 Member variable initialization"); static Book book2 = new Book("static member book2 Member variable initialization"); public Person(String msg) { System.out.println(msg); } Book book3 = new Book("book3 Member variable initialization"); static Book book4 = new Book("static member book4 Member variable initialization"); public static void funStatic() { System.out.println("static Embellished funStatic method"); } public static void main(String[] args) { Person.funStatic(); System.out.println("****************"); Person p1 = new Person("p1 initialization"); } }
The output result is:
In the above example, we can find two interesting places. The first is that when we call a class method through a class without creating an object, although the method does not use any class members, the class members are initialized before the method call. This shows that when we use a class for the first time, the class member initialization will be triggered. The second is that when we use class methods to initialize class members and then new the objects of the class, the static modified class members are not initialized again, which shows that the static modified class members only need to be initialized once during the running process of the program and will not be initialized many times.
After reviewing the initialization of objects, the third function of static is very simple, that is, when we initialize the members decorated with static, we can put them in a block statement starting with static and wrapped in curly braces:
class Book{ public Book(String msg) { System.out.println(msg); } } public class Person { Book book1 = new Book("book1 Member variable initialization"); static Book book2; static { book2 = new Book("static member book2 Member variable initialization"); book4 = new Book("static member book4 Member variable initialization"); } public Person(String msg) { System.out.println(msg); } Book book3 = new Book("book3 Member variable initialization"); static Book book4; public static void funStatic() { System.out.println("static Embellished funStatic method"); } public static void main(String[] args) { Person.funStatic(); System.out.println("****************"); Person p1 = new Person("p1 initialization"); } }
The output result is:
4. Static guide package
Compared with the above three uses, the fourth use may be understood by fewer people, but in fact, it is very simple and more convenient to call class methods. Take the example of "PrintHelper" above as an example. Make a slight change to make it convenient for us to use the static guide package:
/* PrintHelper.java file */ public class PrintHelper { package com.yuteng.study; public static void print(Object o){ System.out.println(o); } }
/* App.java file */import static com.yuteng.study.PrintHelper.*; public class App { public static void main( String[] args ) { print("Hello World!"); } }
The output result is: Hello World!
The above code comes from two java files. The PrintHelper is very simple and contains a static method for printing. And on app In the java file, we first import the PrintHelper class. Here, when importing, we use the static keyword, and add ". *" at the end of the imported class. Its function is to directly import all class methods in the PrintHelper class. Unlike non static import, static import package does not need to use the method of "class name. Method name" to call class methods without conflicting with the method name of the current class. You can directly use "method name" to call class methods, just like the class's own methods.
summary
static is a very important keyword in java, and its usage is also very rich. There are four main uses:
1. It is used to modify the member variable and change it into a member of the class, so as to realize the sharing of all objects for the member;
2. It is used to modify member methods and turn them into class methods. You can directly * * call them by using "class name. Method name". * * is commonly used in tool classes;
3 static block usage, which initializes multiple class members together, making the program more regular. It is very important to understand the initialization process of objects;
4 static guided package usage, which imports the methods of the class directly into the current class, so that the class methods can be called directly using the "method name", which is more convenient.