Java static, this, super, final usage
I. Static
Take a look at the following program:
Public class Hello { Public static void main (string [] ARGs) {// (1) System. Out. println ("Hello, world! "); // (2) } } |
I have read this program, and it is no stranger to most of them who have passed Java mathematics. Even if you have never learned Java and other advanced languages, such as C, you should be able to understand the meaning of this Code. It simply outputs "Hello, world", which is useless at all. However, it shows the main usage of the static keyword.
In section 1, we define a static method named main, which means to tell the Java compiler that I can use this method without creating such an object. How do you run this program? In general, we enter the following command in the command line (with the underline as manual input ):
Javac hello. Java Java hello Hello, world! |
This is the process you run. The first line is used to compile hello. after the Java file is executed, If you view the current file, you will find an additional hello. class file, which is the Java binary bytecode generated in the first line. The second line is the most common practice of executing a Java program. The execution result is as expected. In 2, you may wonder why this is the case. Well, let's break down this statement. (If you have not installed the Java documentation, go to Sun's official website to browse j2se API.) First, the system is located in Java. A core class in the lang package. If you view its definition, you will find a line like this: public static final printstream out. Then, click the hyperlink printstream on the method page, you will see a lot of defined methods, look for println, there will be such a line:
Public void println (string X) |
Well, now you should understand why we need to call it like that. Out is a static variable of system, so we can use it directly, and the class to which out belongs has a println method.
Static Method
Generally, a method is defined as static in a class, that is, this method can be called without the objects of this class. As follows:
Class simple { Static void go (){ System. Out. println ("go ..."); } } Public class Cal { Public static void main (string [] ARGs ){ Simple. Go (); } } |
To call a static method is "class name. Method Name". The usage of the static method is very simple as shown above. Generally, static methods are often used to provide some practical tools for other classes in the application. A large number of static methods in Java class libraries are defined for this purpose.
Static variables
Static variables are similar to static variables. All such instances share this static variable. That is to say, only one bucket is allocated during class loading, and all such objects can control this bucket. Of course, final is another option. See the following code:
Class value { Static int C = 0; Static void Inc (){ C ++; } } Class count { Public static void PRT (string s ){ System. Out. println (s ); } Public static void main (string [] ARGs ){ Value V1, V2; V1 = new value (); V2 = new value (); PRT ("v1.c =" + v1.c + "v2.c =" + v2.c ); V1.inc (); PRT ("v1.c =" + v1.c + "v2.c =" + v2.c ); } } |
The result is as follows:
V1.c = 0 v2.c = 0 V1.c = 1 v2.c = 1 |
This proves that they share a storage zone. Static variables are similar to global variables in C. It is worth exploring the initialization of static variables. We modified the above program:
Class value { Static int C = 0; Value (){ C = 15; } Value (int I ){ C = I; } Static void Inc (){ C ++; } } Class count { Public static void PRT (string s ){ System. Out. println (s ); } Value v = new value (10 ); Static value V1, V2; Static { PRT ("v1.c =" + v1.c + "v2.c =" + v2.c ); V1 = new value (27 ); PRT ("v1.c =" + v1.c + "v2.c =" + v2.c ); V2 = new value (15 ); PRT ("v1.c =" + v1.c + "v2.c =" + v2.c ); } Public static void main (string [] ARGs ){ Count Ct = new count (); PRT ("CT. c =" + CT. V. C ); PRT ("v1.c =" + v1.c + "v2.c =" + v2.c ); V1.inc (); PRT ("v1.c =" + v1.c + "v2.c =" + v2.c ); PRT ("CT. c =" + CT. V. C ); } } |
The running result is as follows:
V1.c = 0 v2.c = 0 V1.c = 27 v2.c = 27 V1.c = 15 v2.c = 15 Ct. c = 10 V1.c = 10 v2.c = 10 V1.c = 11 v2.c = 11 Ct. c = 11 |
This program demonstrates various static initialization features. If you contact Java for the first time, the results may surprise you. It may be confusing to add braces after static. The first thing to tell you is that static variables take precedence over any other non-static variables, regardless of the order in which they appear. As shown in the program, although V appears before V1 and V2, the result is that V1 and V2 are initialized before v. The static {is followed by a piece of code, which is used for explicit static variable initialization. This code will only be initialized once and when the class is loaded for the first time. If you can read and understand this code, it will help you understand the static keyword. When inheritance is involved, the static variables of the parent class will be initialized first, then the static variables of the Child class, and so on. Non-static variables are not the topic of this article and will not be discussed in detail here. Please refer to think in Java.
Static class
Generally, a common class cannot be declared as static. Only one internal class can be declared. In this case, the static internal class can be directly used as a common class without the need to instance an external class. The following code is used:
Public class staticcls { Public static void main (string [] ARGs ){ Outercls. innercls OI = new outercls. innercls (); } } Class outercls { Public static class innercls { Innercls (){ System. Out. println ("innercls "); } } } |
The output result is as expected.
Innercls
It is the same as a normal class. For other usage of internal classes, see the relevant sections in think in Java.
II. This & Super
In the previous section, we discussed various static usage. Using static to define methods or members provides some convenience for programming, to some extent, it is similar to the global functions and global variables in C language. However, it doesn't mean that with this convenience, you can use it everywhere. If so, you need to seriously consider whether you are using object-oriented programming, whether your program is object-oriented. Now, let's start to discuss the meanings and usage of these two keywords.
In Java, this usually refers to the current object, and super refers to the parent class. When you want to reference something of the current object, such as a method of the current object or a member of the current object, you can use this to achieve this purpose. Of course, another purpose of this is to call another constructor of the current object, which will be discussed soon. If you want to reference something of the parent class, it is not super. Since this has some similar characteristics and inherent relationships with super, we will discuss them here, hoping to help you differentiate and master them.
In the general method
The most common situation is that a parameter name in your method has the same name as a member of the current object. In this case, to avoid confusion, you need to explicitly use the this keyword to specify that you want to use a member. The usage is "This. member name. In addition, you can also use "this. "method name" to reference a method of the current object, but this is not necessary at this time. You can directly use the method name to access that method, the compiler will know which one you want to call. The following code demonstrates the above usage:
Public class demothis { Private string name; Private int age; Demothis (string name, int age ){ Setname (name); // you can add this to call the method, like this: This. setname (name); but this is not required. Setage (AGE ); This. Print (); } Public void setname (string name ){ This. Name = Name; // you must specify the member variable to reference. } Public void setage (INT age ){ This. Age = age; } Public void print (){ System. Out. println ("name =" + name + "age =" + age); // This does not need to be used in this line, because there is no obfuscation } Public static void main (string [] ARGs ){ Demothis dt = new demothis ("Kevin", "22 "); } } |
This code is very simple and you should be able to understand it without explaining it. In the constructor, you can use this. Print () instead of print. Next we will modify this program to demonstrate the usage of super.
Class person { Public int C; Private string name; Private int age; Protected void setname (string name ){ This. Name = Name; } Protected void setage (INT age ){ This. Age = age; } Protected void print (){ System. Out. println ("name =" + name + "age =" + age ); } } Public class demosuper extends person { Public void print (){ System. Out. println ("demosuper :"); Super. Print (); } Public static void main (string [] ARGs ){ Demosuper DS = new demosuper (); DS. setname ("Kevin "); DS. setage (22 ); DS. Print (); } } |
In demosuper, the re-defined print method overwrites the print method of the parent class. It first does something of its own, and then calls the overwritten method of the parent class. The output shows this:
Demosuper:
Name = Kevin age = 22
This method is commonly used. In addition, if the members of the parent class can access the quilt class, you can use it like this and use "super. in the parent class, but you often do not access the Member names in the parent class in this way.
In the constructor
Constructor is a special method that is automatically called during object initialization. In the constructor, this and super also have various usage methods described above, and they also have special features. Please refer to the following example:
Class person { Public static void PRT (string s ){ System. Out. println (s ); } Person (){ PRT ("A person ."); } Person (string name ){ PRT ("A person name is:" + name ); } } Public class Chinese extends person { Chinese (){ Super (); // call the parent class Constructor (1) PRT ("A Chinese."); // (4) } Chinese (string name ){ Super (name); // call the constructor with the same parameters in the parent class (2) PRT ("His name is:" + name ); } Chinese (string name, int age ){ This (name); // call a constructor with the same parameters currently (3) PRT ("his age is:" + age ); } Public static void main (string [] ARGs ){ Chinese Cn = new Chinese (); CN = new Chinese ("Kevin "); CN = new Chinese ("Kevin", 22 ); } } |
In this program, this and super no longer use ". "connects a method or member, but directly follows the appropriate parameter, so its meaning changes. Super is used to call constructors with the same form in the parent class, such as 1 and 2. If this is followed by a parameter, the constructor with the same parameter is called, for example, 3. Of course, in each overload constructor in Chinese, the usage of this and super in general methods can still be used. For example, you can replace it with "This. PRT (because it inherits the method in the parent class) or "super. PRT (because it is a method in the parent class and can be accessed by the quilt class), it can still run correctly. However, it seems a bit fascinating.
At last, I wrote so much. If you keep in mind the phrase "this usually refers to the current object, super usually refers to the parent class", then this article achieves the goal, others you will learn and master in future programming practices. For the inheritance mentioned in this article, refer to the relevant Java tutorial.
Iii. Final
Final is not commonly used in Java, but it provides functions such as defining constants in C language, final also allows you to control whether your members, methods, or a class can be overwritten or inherited. These features enable final to play an indispensable role in Java, it is also one of the keywords that must be known and mastered when learning Java.
Final member
When you define a variable in a class and add the final keyword before it, this variable cannot be changed once initialized, the unchangeable meaning here is that its value is immutable for the basic type, and its reference for the object variable cannot be changed. It can be initialized in two places. One is its definition, that is, it is assigned a value directly when the final variable is defined, and the other is in the constructor. You can only choose one of these two places, either give a value at the time of definition, or give a value in the constructor, not both at the time of definition, in the constructor, another value is given. The following code demonstrates this point:
Import java. util. List; Import java. util. arraylist; Import java. util. Collections list; Public class bat { Final Pi = 3.14; // address value when defined Final int I; // The value cannot be given here because Initialization is required in the constructor. Final list; // This variable is also the same as above BAT (){ I = 100; List = new vertex list (); } BAT (int ii, list l ){ I = II; List = L; } Public static void main (string [] ARGs ){ Bat B = new bat (); B. List. Add (new bat ()); // B. I = 25; // B. List = new arraylist (); System. Out. println ("I =" + B. I + "list type:" + B. List. getclass ()); B = new bat (23, new arraylist ()); B. List. Add (new bat ()); System. Out. println ("I =" + B. I + "list type:" + B. List. getclass ()); } } |
This program demonstrates the general usage of final. Here we use the initialization method in the constructor, which gives you a little flexibility. As shown in the two overloaded constructors of BAT, the first default constructor will provide you with the default value. The overloaded constructor will initialize the final variable based on the value or type you provided. However, sometimes you don't need this flexibility. You just need to set the value at the time of definition and never change. In this case, you don't need to use this method. There are two lines of statements commented out in the main method. If you remove the comment, the program will not be able to compile. This is to say, whether it is the value of I or the type of list, once initialized, it cannot be changed. However, B can specify the I value or list type through reinitialization. This is shown in the output:
I = 100 list type: Class java. util. Category list I = 23 list type: Class java. util. arraylist |
Another method is to define the final parameter in the method. For variables of the basic type, this method has no practical significance, because the variables of the basic type are passed values when calling the method, that is to say, you can change this parameter variable in the method without affecting the call statement. However, it is very practical for the object variable because the object variable is passed with its reference during transmission, in this way, your modification to the object variable in the method will also affect the object variable in the call statement. When you do not need to change the object variable used as the parameter in the method, use final to declare it, it will prevent you from accidentally modifying the call method.
In addition, when the internal class in the method uses the variable in the method, this parameter must be declared as final for use, as shown in the following code:
Public class inclass { Void innerclass (final string Str ){ Class iclass { Iclass (){ System. Out. println (STR ); } } Iclass Ic = new iclass (); } Public static void main (string [] ARGs ){ Inclass Inc = new inclass (); Inc. innerclass ("hello "); } } |
Final Method
If you declare the method as final, it means that you already know that the function provided by this method has met your requirements and does not need to be extended, this method cannot be overwritten by any class inherited from this class, but inheritance can still inherit this method, that is, it can be used directly. In addition, there is a mechanism called inline, which enables you to directly Insert the method subject into the call when calling the final method, rather than performing routine method calls, such as saving breakpoints, this may improve the program efficiency. However, when your method subject is very large, or you call this method in multiple places, your calling subject code will expand rapidly, which may affect the efficiency. Therefore, use final for method definition with caution.
Final class
When using final on a class, you need to consider it carefully. Because a final class cannot be inherited by anyone, it means that this class is a leaf class in an inheritance tree, in addition, such designs have been considered perfect without modification or expansion. For members in the final class, you can define it as final or not final. For methods, because the class is final, they naturally become final. You can also explicitly add a final to the methods in the final class, but this is obviously meaningless.
The following program demonstrates the usage of the final method and final class:
Final class final { Final string STR = "final data "; Public String str1 = "non final data "; Final public void print (){ System. Out. println ("final method ."); } Public void what (){ System. Out. println (STR +" "+ Str1 ); } } Public class finaldemo {// extends final cannot be inherited Public static void main (string [] ARGs ){ Final F = new final (); F. What (); F. Print (); } } |
It can be seen from the program that there is almost no difference between the use of final classes and common classes, but it loses its inherited features. The difference between the final method and the non-final method is also difficult to see from the program line, just remember to use it with caution.
Application of final in Design Mode
In the design pattern, there is a pattern called the immutable pattern. in Java, this pattern can be easily implemented through the final keyword. It explains the program bat used by final members. java is an example of the unchanged mode. If you are interested in this, you can refer to the explanation in the book "Java and mode" written by Dr. Yu Hong.
So far, the use of this, static, supert and final has been completed. If you have been able to roughly express the differences and usage of these four keywords, it means that you have mastered it. However, nothing in the world is perfect. Java provides these four keywords, which brings great convenience to the programming of programmers, but it does not mean that you should use them everywhere, once an abused program is reached, it is counterproductive. Therefore, you must carefully consider it when using it.