A detailed introduction to the sequence of object initialization in Java _java

Source: Internet
Author: User

Objective

In Java, an object must be properly initialized before it can be used, as specified by the Java specification. Recently I found an interesting question, the answer to this question at first glance cheated my eyes. Take a look at these three categories:

Package com.ds.test;

public class Upper {
 String upperstring;

 Public Upper () {
 initializer.initialize (this);
 }
}
Package com.ds.test;

public class Lower extends Upper {

 String lowerstring = null;

 Public Lower () {
 super ();
 System.out.println ("Upper:" + upperstring);
 System.out.println ("Lower:" + lowerstring);
 }

 public static void Main (final string[] args) {
 new Lower ();
 }
}
Package com.ds.test;
public class initializer {
 static void Initialize (final Upper anupper) {
 if (anupper instanceof Lower) {
 Lo Wer lower = (lower) anupper;
 lower.lowerstring = "lowerinited";
 }
 anupper.upperstring = "upperinited";
 }
}

Lower What output can I get from running this class? It is easier to see the whole situation in this minimalist example, but in reality there is a lot of code that distracts one's attention.

Anyway, the output is like this:

upper:upperinited
Lower:null;

Although the type is used in the small example String , the Initializer actual code of the class has a delegate object for registration that is the same as the Lower function of the class-at least the Lower class is the intent. However, for some reason it is not working when you run the application. Instead, the default path is used, and the delegate object is not set (null).

Now change Lower the code a little bit:

Package com.ds.test;

public class Lower extends Upper {

 String lowerstring;

 Public Lower () {
 super ();
 System.out.println ("Upper:" + upperstring);
 System.out.println ("Lower:" + lowerstring);
 }

 public static void Main (final string[] args) {
 new Lower ();
 }
}

Now the output is like this:

upper:upperinited
lower:lowerinited

Do you see the difference in the code?

Yes, this lowerString field is no longer explicitly set to NULL. Why does this have to be different. Anyway is the default value for the Reference type field (for example, here String ) not empty? Of course it's empty. It turns out that although this slight change obviously doesn't change the behavior of the code in any way, it makes the results different.

So, what's going on? When you look at the initialization order, everything becomes clear:

1. main() The function calls the Lower constructor.

2. Lower An example is prepared. means that all fields are created and the default values are populated, for example, the default value for the reference type is NULL, and the default value for the Boolean type is false . At this point, any inline assignment to the field does not occur.

3. The parent class constructor was invoked. This is enforced by the characteristics of the language. So before anything else happens, the Upper constructor is invoked.

4.Upper This constructor runs and specifies a reference that points to the Initializer.initialize() newly created instance of the method.

5. Initializer the class is attached with a new string of two fields ( upperString and lowerString ). Assigning values to those two fields by using a bit of a dirty instanceof instance check-this is not a particularly good design pattern, but it is also feasible, not so much. Once it happens, upperString lowerString the references are no longer empty.

6. Initializer.initialize() The call completes, the Upper constructor is also completed.

7. Now it becomes interesting: Lower The construction of the instance continues. Assuming lowerString there is no explicit assignment in the declaration of the field =null , the Lower constructor resumes execution and prints out two strings connected to the field.

However, if there is an explicitly assigned null operation, the execution process is slightly different: when the parent class constructor completes, any variable initialization executes (see the Java Language Specification section 12.5) before the remaining constructors run. In this case, the lowerString string reference that was assigned before will not be assigned null again. Then continue with the rest of the function constructs, and now lowerString the printed value is: null.

This is a good example of how we can pay attention to the details of creating objects (or where to look at Java coding specifications, print or online) and why it's bad to write initialization like this. We should not care about Upper subclasses at all. Conversely, if initialization of some fields for some reason cannot be done in the subclass itself, it will only need some variant of its own initialization help class. In this case, if you use String lowString or String lowerString = null really make no difference, what it should be.

Summarize

The above is the entire content of this article, I hope this article content for everyone's study or work can bring some help, if there are questions you can message exchange.

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.