Forward references in Java

Source: Internet
Author: User

The so-called forward reference is to use them before defining classes, interfaces, methods, variables, for example,

Class MyClass
{
    void method ()
    {
        System.out.println (myvar);
    }
    String MyVar = "var value";
}

MyVar is defined after method methods, but the method can use the variable first. In many languages, such as C + +, it needs to be defined ahead of time, and Java has allowed forward references. However, it may be easier to make mistakes when using forward references. For example, the following code.

Class MyClass {
     int method () {return n;}
     int m = method ();
     int n = 1;
}

If you simply execute the following code, you will no doubt output 1.

System.out.println (New MyClass (). method ());

But use the following code output variable m, but get 0.

System.out.println (New MyClass (). m);

So what's the real deal?

In fact, from the Java compiler and runtime working principle can be learned. The Java source code is compiled with lexical, grammatical, and semantic detection, and if passed, the. class file is generated. However, the variables in MyClass are not initialized, and the compiler simply records the corresponding initialization expression (method (), 1) in the. class file.

When runtime runs Myclass.class, the member fields are loaded first, and the load is executed sequentially. It does not initialize all the values that can be initialized because Java supports forward references. First, runtime initializes the M field, which, of course, calls method methods, using the forward reference technique in the method methods to use N. But then the n hasn't been initialized yet. Runtime to implement forward references, you need to add all fields to the symbol table before you initialize all the fields. These fields can be referenced anywhere (but need to satisfy the Java calling rules), but because these fields have not yet been initialized, all the fields in the symbol table use the default values. The default value for a field of type int is naturally 0. So when the int m = Method () is initialized, the n that the methods access is actually the field n that has been added to the symbol table before the formal initialization, not the result of the following int n = 1. But by changing the MyClass into the following form, the result is completely different.

Class MyClass {
    int method () {return n;}
    int n = 1;
    int m = method ();
}

Now execute the following code and output 1.

System.out.println (New MyClass (). m);

The reason for this is that the method is invoked when referring to the initialization of M, and the n used in it is already initialized, not the value originally placed in the symbol table.

In combination with the above, runtime when running the. class file, a symbol table for each scope (method, interface, class, and so on, with its own scope) is accessed at least two times, and the first time all of the fields (consider the initialization of the class only) are placed in the symbol table, and the initialization is not considered for the moment. Being placed in a symbol table is just the equivalent of an index so that other places can find them when referencing the field, for example, when you refer to N in the methods method, you look for n in the symbol table, but then n is just the default value for type int. Wait until the second access n is the real initialization of n (int n = 1). This is to update the value of the field n stored in the symbol table to the actual initialization value (1). So if the reference n is released before the formal initialization of N, of course the output is 0.

Then maybe someone will ask, first access to n, then access to M, then the value of M is 1? The answer is still 0. Because the initialization of M and N is complete when the MyClass object is created, their values are facts and cannot be changed unless they are set again.

MyClass MyClass = new MyClass ();
System.out.println (MYCLASS.N);  Output 1
System.out.println (MYCLASS.M);  still output 0

For static members, this rule is still met.

Class MyClass {
     static int method () {return n;}
     static int m = Method ();  direct access to M, still output 0
     static int n = 1;
}

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.