Keywords Java (Power node Java College)

  • 2020-06-19 10:09:36
  • OfStack

When we use the this keyword in Java, we usually know that this represents the current instance of the method that is calling the class. In general, it is easy to understand the this keyword. However, when I was a beginner, I had a question that I could not clearly understand. Now I gradually understand it, so I want to write it down. Let's take a quick look at what this does in general. Consider the following code:


public class Leaf {
 private int i = 0;
 Leaf increment() {
  i++;
  return this;
 }
 void print() {
  System.out.println("i = " + i);
 }
 public static void main(String[] args) {
  Leaf x = new Leaf();
  x.increment().increment().print();
 }
}

In the main method of the Leaf class, we have one instance of Leaf, x, and then the x instance is called increment() Methods. If increment() is the common method or void method, there is nothing worth studying here. In particular, in increment() In the method, our return is 1 this, and this this represents the x we just created. Because x is calling the increment() method, increment() Method this clearly represents an instance of x of Leaf.

This doesn't seem like much to discuss, this is the instance that represents calling this method, x. However, suppose we change the main() function to look like this


public static void main(String[] args) {
 Leaf x = new Leaf();
 x.increment().increment().print();
  
 Leaf y = new Leaf();
 y.increment().increment().print();
}

In the above modified code, we created an additional instance of Leaf y, and then y called increment() twice in a row. Now the question is, if x and y call the increment() method at the same time, who exactly does this represent? You might think there's something wrong with this. x calls increment(), this for x, y for increment(), this for y. The problem is, when we talk about calling methods, at the jvm level we find the Leaf class increment() Method, then create the stack frame in the java virtual machine stack.

The code inside the method is then executed in the stack frame. Now you can see that at the jvm execution method level, there is no such thing as an x call, y call, so how does this in the method determine which instance to point to?

Let's look at the Leaf class bytecode and see if we're missing something. If we don't pass an instance of x or an instance of y into a method, it's impossible to know which instance this refers to when jvm executes the method.

Over here, we see in the increment() Method, there are no arguments in the code, but the number of arguments in the bytecode is 1. The result is obvious when you think about it: when jvm performs compilation, it passes 1 argument by default in the instance method, which is the instance being called. For example, x call, hide and pass x, y call, pass y. Therefore, our this is able to determine at the jvm execution method level who exactly is pointing to.

The above conclusion is inferred by ourselves. Is there a book that describes this in detail? In java Programming Ideas, this piece is described as follows:

Suppose we are inside a method and want to get a handle to the current object. Since that handle is passed "secretly" by the compiler, no identifier is available. However, there is a special keyword for this purpose: this.

The handle that the compiler passes in secret is the one we have here.

By this point, the description of this must be clear and we understand it at the level of jvm. So, are you interested in taking a look at the example below and thinking about what this stands for in the base class B?


public class B {
 public B() {
  System.out.println(this.getClass().getSimpleName()); 
  System.out.println(((A) this).a); 
 }
}
public class A extends B {
 public int a = 100;  
 public A() {
  a = 200;
 } 
 public static void main(String[] args) {
  new A();
 }
}

This example is intended to show how the java class is initialized when it has an inheritance structure, but the constructor in the B class is special: the this constructor in the B class outputs SimpleName. In general, we have the situation that B in B class output SimpleName should be B, but here is A? Why is that?

This was already covered when we talked about this above. When the java method is called to create a stack frame, jvm passes the current instance secretly. Therefore, when we execute the constructor of A, the default is to call the constructor of the parent class B. When we call the constructor of the parent class B, the current instance passed in secretly is an instance of A -- B is called in the constructor of A, so this stands for A.


Related articles: