Use, usage and examples of static, this, super, final in Java

Original link: https://www.cnblogs.com/zjfjava/p/6337932.html
1. static

Please look at the following program first:

public class Hello {
	public static void main(String[] args){ //(1)
	System.out.println("Hello,world!"); //(2) }
}

After reading this program, it is no stranger to most people who have studied Java. Even if you haven't learned Java, and have learned other high-level languages, such as C, then you should be able to understand the meaning of this code. It simply outputs "Hello, world" and has no other use at all. However, it shows the main usage of the static keyword.

At 1, we defined a static method named main, which means telling the Java compiler that I can use this method without creating an object of this type. Do you still have to run this program? Generally, we enter the following commands on the command line (underlined for manual input):

javac Hello.java

java Hello

Hello,world!

This is the process you run. The first line is used to compile the Hello.java file. After execution, if you look at the current one, you will find an additional Hello.class file, which is the Java binary byte code generated by the first line. . The second line is the most common way to execute a Java program. The execution results are as you expected. In 2, you may wonder why this is necessary to output. Ok, let's break down this sentence. (If Java documentation is not installed, please go to Sun's official website to browse the J2SE API) First, System is a core class located in the java.lang package. If you look at its definition, you will find a line like this: public static final PrintStream out; Then go further, click the PrintStream hyperlink, on the METHOD page, you will see a lot of defined methods, find println, there will be a line like this:

public void println(String x)

Ok, now you should understand why we have to call it that way, out is a static variable of System, so it can be used directly, and the class to which out belongs has a println method.

Static method

Usually, a method is defined as static in a class, that is to say, this method can be called without the object 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();
	 }
}

Calling a static method is "class name. Method name", the use of static method is very simple as shown above. In general, static methods often provide some utility tools for other classes in the application. A large number of static methods in the Java class library are defined for this purpose.

Static variable

Static variables are similar to static methods. All such instances share this static variable, which means that when the class is loaded, only one storage space is allocated, and all such objects can manipulate this block storage space, of course, it is a different matter for final. Look at 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 results are as follows:

v1.c=0 v2.c=0
v1.c=1 v2.c=1

This proves that they share a storage area. Static variables are somewhat similar to the concept of global variables in C. It is worth discussing the initialization of static variables. We modify 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 results are 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 characteristics of static initialization. If you are new to Java, the results may surprise you. You may be confused by adding parentheses after static. The first thing to tell you is that statically defined variables will 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 the initialization of v1 and v2 precedes 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 first loaded. If you can read and understand this code, it will help you understand the static keyword. When it comes to inheritance, the static variables of the parent class will be initialized first, then the subclasses, and so on. Non-static variables are not the subject of this article and will not be discussed in detail here. Please refer to the explanation in Think in Java.

Static class

Usually an ordinary class is not allowed to be declared static, only an inner class can. At this time, the inner class declared as static can be used directly as a normal class without having to instantiate an outer class.

As shown in the following code:

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 will be as you expected.

InnerCls

Same as ordinary class. For other usage of internal classes, please refer to the relevant chapters in Think in Java, which will not be explained in detail here.

二、this & super

In the previous section, we discussed various uses of static. By using static to define methods or members, it provides some convenience for our programming. To a certain extent, it can be said that it is similar to global functions and global variables in C language. . However, it does not mean that with this convenience, you can use it everywhere. If so, you need to seriously consider whether you are programming with object-oriented thinking and whether your program is object-oriented. Okay, now let ’s discuss the meaning and usage of the two keywords this & super.

In Java, this usually refers to the current object, and super refers to the parent class. When you want to reference something in 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 use of this is to call the current object Another constructor, these will be discussed soon. If you want to refer to something in the parent class, it is super. Since this and super have some similar characteristics and a certain inherent relationship, we will discuss it in this section, hoping to help you distinguish and master them.

In the general method, the most common situation is that a formal parameter name in your method has the same name as a member of the current object. At this time, in order not to be confused, you need to use this keyword explicitly. Indicate that you want to use a member, the method is "this. Member name", and the one without this is the formal parameter. In addition, you can also use "this. Method name" to refer to 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 that you are calling that one. The following code demonstrates the above usage:

public class DemoThis{
	private String name;
	private int age;
	DemoThis(String name,int age){
		setName(name); //你可以加上this来调用方法,像这样:this.setName(name);但这并不是必须的
		setAge(age);
		this.print();
	} 
	public void setName(String name){
		this.name=name;//此处必须指明你要引用成员变量
	}
	public void setAge(int age){
		this.age=age;
	}
	public void print(){
		System.out.println("Name="+name+" Age="+age);//在此行中并不需要用this,因为没有会导致混淆的东西
	}
	public static void main(String[] args){
		DemoThis dt=new DemoThis("Kevin","22");
	}
}

This code is very simple and you should be able to read it without explanation. You see this.print () in the constructor. You can replace it with print (). Both have the same effect. Below we 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 redefined print method overwrites the print method of the parent class. It first does its own thing, and then calls the overridden method of the parent class. The output shows this:

DemoSuper:

Name=kevin Age=22

This method of use is relatively common. In addition, if the members of the parent class can be accessed by the child class, you can use it like this, using the "super. Member name in the parent class", but often you do not access the member name in the parent class like this .

The constructor is a special method that is automatically called when the object is initialized. In the constructor, this and super also have various uses mentioned above, and it has special places, please see 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(); //调用父类构造函数(1)
		prt("A chinese.");//(4)
	}
	Chinese(String name){
		super(name);//调用父类具有相同形参的构造函数(2)
		prt("his name is:"+name);
	}
	Chinese(String name,int age){
		this(name);//调用当前具有相同形参的构造函数(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 "." To connect a method or member as before, but directly follow up with appropriate parameters, so its meaning has changed. The parameter after super is used to call the constructor of the same form in the parent class, such as 1 and 2. Adding parameters after this calls the current constructor with the same parameters, such as 3. Of course, in the various overloaded constructors of Chinese, various usages of this and super in general methods can still be used, such as 4 places, you can replace it with "this.prt" (because it inherits the parent class The method in) or "super.prt" (because it is a method in the parent class and can be accessed by the subclass), it can still run correctly. But this seems to add a bit of flavor.

Finally, I have written so much. If you can keep in mind the phrase "this usually refers to the current object, super usually refers to the parent class", then this article has achieved its purpose, and other self-will will be practiced in future programming Slowly realize and master it. In addition, regarding the inheritance mentioned in this article, please refer to the relevant Java tutorial.

Three, final

Final is not commonly used in Java, but it provides us with functions such as defining constants in C language. Not only that, final also allows you to control whether your members, methods or a class can be overwritten or inherited, etc. Functions, these characteristics make final have an indispensable position in Java, and 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, add the final keyword in front of it, that is to say, once this variable is initialized, it cannot be changed. The immutable meaning here is that the value of the basic type is immutable, and For object variables, the reference cannot be changed. Its initialization can be in two places, one is its definition, which means that it is directly assigned to the final variable when it is defined, and the other is in the constructor. You can only choose one of these two places. You can either give a value when you define it or give it a value in the constructor. You cannot give both a value when you define it and another value in the constructor. The following code demonstrates this:

import java.util.List;

import java.util.ArrayList;

import java.util.LinkedList;

public class Bat{
	final PI=3.14; //在定义时便给址值
	final int i; //因为要在构造函数中进行初始化,所以此处便不可再给值
	final List list; //此变量也与上面的一样

	Bat(){
		i=100;
		list=new LinkedList();
	}

	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 simply demonstrates the regular usage of final. Use the initialization method in the constructor here, which gives you a little flexibility. As shown in Bat's two overloaded constructors, the first default constructor will provide you with the default value, and the overloaded constructor will initialize the final variable according to the value or type you provide. However, sometimes you do not need this flexibility, you only need to give its value when it is defined and never change, then do not use this method again. There are two lines of comments in the main method. If you remove the comment, the program cannot be compiled. This means that no matter the value of i or the type of list, once initialized, it can't be changed anymore. However, b can be re-initialized to specify the value of i or the type of list, which is shown in the output:

I=100 List Type:class java.util.LinkedList

I=23 List Type:class java.util.ArrayList

Another usage is to define the parameter in the method as final. For variables of the basic type, this does not have any practical significance, because the variables of the basic type are passed by value when calling the method, that is to say, you can change it in the method This parameter variable does not affect the calling statement, but it is very practical for the object variable, because the object variable is passed its reference when passed, so that your modification of the object variable in the method will also affect the calling statement Object variables, when you do not need to change the object variable as a parameter in the method, explicitly use final to declare, which will prevent you from inadvertently modifying it and affecting the calling method.

In addition, when the inner class in the method uses the parameter in the method, this parameter must also be declared as final before it can be used, 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

Declare the method as final, which means that you already know that the function provided by this method has met your requirements, no extension is required, and no class that inherits from this class is allowed to override this method, but inheritance can still inherit this method , Which means it can be used directly. There is also a mechanism called inline, which allows you to directly insert the method body into the calling place when calling the final method instead of making routine method calls, such as saving breakpoints, pushing the stack, etc., which may Make your program more efficient. However, when your method body is very large, or you call this method in multiple places, then your calling body code will quickly expand, which may affect efficiency, so you should use it with caution Final method definition.

final class

When you use final on a class, you need to think carefully, because a final class cannot be inherited by anyone, that means that this class is a leaf class in an inheritance tree, and the design of this class It has been considered perfect without modification or expansion. For the members of the final class, you can define it as final or not. For the method, because the class belongs to the final relationship, it naturally becomes final. You can also explicitly add a final method to the final class, but this is obviously meaningless.

The following program demonstrates the use of final methods and final classes:

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 无法继承
	public static void main(String[] args){
		final f=new final();
		f.what();
		f.print();
	}
}

It can be seen from the program that the use of the final class is almost the same as that of the ordinary class, except that it loses the inherited characteristics. 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

There is a pattern in the design pattern called invariant pattern. This pattern can be easily implemented in Java through the final keyword. The program Bat.java used when explaining the final member is an example of invariant pattern. If you are interested in this, you can refer to the explanation in the book "Java and Patterns" written by Dr. Yan Hong.

So far, the use of this, static, supert and final has been finished. If you can already roughly tell the difference and usage of these four keywords, it means that you have basically mastered it. However, nothing in the world is perfect. Java provides these four keywords, which brings great convenience to programmers, but it is not to let you use it everywhere. Once you reach the abused program, This is counterproductive, so be sure to consider carefully when using it.
<Remarks: The content of the original blogger is well written, but I think this code style is really a headache>

Released six original articles · won praise 0 · Views 4855

Guess you like

Origin blog.csdn.net/weixin_44479378/article/details/93055589