Class and object initialization in Java

Acquire how to to initialize Java classes and objects for successful JVM execution

Classes and objects in Java must be initialized before they are used. You've previously learned that form fields are initialized to default values when classes are loaded and that objects are initialized via constructors, but there is more than to initialization. This article introduces all of Java's features for initializing classes and objects.

download

Download the source lawmaking for example applications in this tutorial. Created by Jeff Friesen for JavaWorld.

How to initialize a Java class

Before nosotros explore Java's support for class initialization, allow's recap the steps of initializing a Java course. Consider List 1.

Listing one. Initializing form fields to default values

              course SomeClass {    static boolean b;    static byte past;    static char c;    static double d;    static bladder f;    static int i;    static long 50;    static brusque southward;    static String st; }            

Listing ane declares class SomeClass. This class declares 9 fields of types boolean, byte, char, double, float, int, long, short, and String. When SomeClass is loaded, each field'southward $.25 are set up to zero, which you interpret every bit follows:

              false 0 \u0000 0.0 0.0 0 0 0 nada            

The previous class fields were implicitly initialized to zero. Notwithstanding, you can also explicitly initialize class fields by directly assigning values to them, as shown in Listing 2.

Listing 2. Initializing class fields to explicit values

              class SomeClass {    static boolean b = true;    static byte past = one;    static char c = 'A';    static double d = 2.0;    static bladder f = 3.0f;    static int i = 4;    static long fifty = 5000000000L;    static short s = 20000;    static String st = "abc"; }            

Each assignment's value must exist type-compatible with the grade field's type. Each variable stores the value directly, with the exception of st. Variable st stores a reference to a String object that contains abc.

Referencing class fields

When initializing a class field, information technology'due south legal to initialize it to the value of a previously initialized class field. For example, Listing 3 initializes y to ten's value. Both fields are initialized to ii.

Listing 3. Referencing a previously alleged field

              class SomeClass {    static int x = ii;    static int y = x;     public static void main(String[] args)    {       System.out.println(x);       Organization.out.println(y);    } }            

Withal, the reverse is not legal: you lot cannot initialize a class field to the value of a subsequently declared grade field. The Java compiler outputs illegal forrad reference when it encounters this scenario. Consider Listing 4.

Listing 4. Attempting to reference a afterward declared field

              class SomeClass {    static int 10 = y;    static int y = 2;     public static void main(String[] args)    {       System.out.println(x);       System.out.println(y);    } }            

The compiler will report illegal frontwards reference when it encounters static int ten = y;. This is because source code is compiled from the acme down, and the compiler hasn't yet seen y. (It would likewise output this message if y wasn't explicitly initialized.)

Class initialization blocks

In some cases you lot may want to perform complex form-based initializations. You will do this after a form has been loaded and before any objects are created from that form (assuming that the grade isn't a utility class). You tin can apply a grade initialization block for this task.

A class initialization block is a cake of statements preceded past the static keyword that's introduced into the class'southward torso. When the class loads, these statements are executed. Consider Listing 5.

Listing 5. Initializing arrays of sine and cosine values

              grade Graphics {    static double[] sines, cosines;    static    {       sines = new double[360];       cosines = new double[360];       for (int i = 0; i < sines.length; i++)       {          sines[i] = Math.sin(Math.toRadians(i));          cosines[i] = Math.cos(Math.toRadians(i));       }    } }            

Listing 5 declares a Graphics class that declares sines and cosines array variables. It too declares a form initialization block that creates 360-element arrays whose references are assigned to sines and cosines. It so uses a for statement to initialize these array elements to the appropriate sine and cosine values, past calling the Math form'due south sin() and cos() methods. (Math is office of Java'due south standard class library. I'll discuss this class and these methods in a future article.)

Combining class field initializers and class initialization blocks

You can combine multiple course field initializers and class initialization blocks in an application. List 6 provides an example.

Listing 6. Performing form initialization in tiptop-downward gild

              class MCFICIB {    static int ten = 10;     static double temp = 98.vi;     static    {       System.out.println("x = " + ten);       temp = (temp - 32) * 5.0/ix.0; // catechumen to Celsius       System.out.println("temp = " + temp);    }     static int y = x + five;     static    {       Organisation.out.println("y = " + y);    }     public static void main(String[] args)    {    } }            

Listing 6 declares and initializes a pair of grade fields (x and y), and declares a pair of static initializers. Compile this listing as shown:

              javac MCFICIB.coffee            

Then run the resulting awarding:

              java MCFICIB            

Yous should detect the following output:

              x = ten temp = 37.0 y = 15            

This output reveals that class initialization is performed in top-down order.

<clinit>() methods

When compiling class initializers and class initialization blocks, the Java compiler stores the compiled bytecode (in meridian-downwards lodge) in a special method named <clinit>(). The bending brackets forestall a name disharmonize: you cannot declare a <clinit>() method in source code because the < and > characters are illegal in an identifier context.

After loading a class, the JVM calls this method before calling main() (when main() is nowadays).

Let'southward take a look within MCFICIB.form. The following partial disassembly reveals the stored information for the 10, temp, and y fields:

              Field #1  00000290        Access Flags                          ACC_STATIC 00000292        Name                                  10 00000294        Descriptor                            I 00000296        Attributes Count                      0  Field #ii  00000298        Access Flags                          ACC_STATIC 0000029a        Proper noun                                  temp 0000029c        Descriptor                            D 0000029e        Attributes Count                      0  Field #iii  000002a0        Admission Flags                          ACC_STATIC 000002a2        Name                                  y 000002a4        Descriptor                            I 000002a6        Attributes Count                      0            

The Descriptor line identifies the JVM's type descriptor for the field. The type is represented by a single letter of the alphabet: I for int and D for double.

The post-obit fractional disassembly reveals the bytecode education sequence for the <clinit>() method. Each line starts with a decimal number that identifies the zero-based offset accost of the subsequent instruction:

                              0        bipush ten   2        putstatic MCFICIB/x I   5        ldc2_w #98.6   8        putstatic MCFICIB/temp D  xi        getstatic java/lang/System/out Ljava/io/PrintStream;  14        new coffee/lang/StringBuilder  17        dup  18        invokespecial java/lang/StringBuilder/<init>()V  21        ldc "x = "  23        invokevirtual java/lang/StringBuilder/append(Ljava/lang/String;)Ljava/lang/StringBuilder;  26        getstatic MCFICIB/x I  29        invokevirtual java/lang/StringBuilder/append(I)Ljava/lang/StringBuilder;  32        invokevirtual java/lang/StringBuilder/toString()Ljava/lang/String;  35        invokevirtual java/io/PrintStream/println(Ljava/lang/String;)V  38        getstatic MCFICIB/temp D  41        ldc2_w #32  44        dsub  45        ldc2_w #5  48        dmul  49        ldc2_w #9  52        ddiv  53        putstatic MCFICIB/temp D  56        getstatic java/lang/System/out Ljava/io/PrintStream;  59        new java/lang/StringBuilder  62        dup  63        invokespecial java/lang/StringBuilder/<init>()V  66        ldc "temp = "  68        invokevirtual java/lang/StringBuilder/suspend(Ljava/lang/Cord;)Ljava/lang/StringBuilder;  71        getstatic MCFICIB/temp D  74        invokevirtual java/lang/StringBuilder/append(D)Ljava/lang/StringBuilder;  77        invokevirtual java/lang/StringBuilder/toString()Ljava/lang/String;  80        invokevirtual coffee/io/PrintStream/println(Ljava/lang/String;)V  83        getstatic MCFICIB/10 I  86        iconst_5  87        iadd  88        putstatic MCFICIB/y I  91        getstatic coffee/lang/System/out Ljava/io/PrintStream;  94        new java/lang/StringBuilder  97        dup  98        invokespecial java/lang/StringBuilder/<init>()V 101        ldc "y = " 103        invokevirtual java/lang/StringBuilder/append(Ljava/lang/Cord;)Ljava/lang/StringBuilder; 106        getstatic MCFICIB/y I 109        invokevirtual coffee/lang/StringBuilder/append(I)Ljava/lang/StringBuilder; 112        invokevirtual java/lang/StringBuilder/toString()Ljava/lang/String; 115        invokevirtual java/io/PrintStream/println(Ljava/lang/String;)V 118        return            

The didactics sequence from starting time 0 through kickoff two is equivalent to the following class field initializer:

              static int x = ten;            

The education sequence from get-go v through beginning viii is equivalent to the following class field initializer:

              static double temp = 98.6;            

The instruction sequence from showtime eleven through starting time 80 is equivalent to the following form initialization block:

              static {    System.out.println("x = " + x);    temp = (temp - 32) * 5.0/ix.0; // catechumen to Celsius    System.out.println("temp = " + temp); }            

The didactics sequence from offset 83 through offset 88 is equivalent to the following class field initializer:

              static int y = x + 5;            

The instruction sequence from offset 91 through get-go 115 is equivalent to the following class initialization block:

              static {    Organisation.out.println("y = " + y); }            

Finally, the return didactics at offset 118 returns execution from <clinit>() to that function of the JVM that called this method.

How to initialize objects

After a grade has been loaded and initialized, you'll oftentimes want to create objects from the grade. As you learned in my recent introduction to programming with classes and objects, y'all initialize an object via the code that you lot place in a course's constructor. Consider List 7.

List 7. Using the constructor to initialize an object

              class City {    private String name;    int population;     City(Cord name, int population)    {       this.name = proper name;       this.population = population;    }     @Override    public Cord toString()    {       return proper noun + ": " + population;    }     public static void main(String[] args)    {       City newYork = new City("New York", 8491079);       System.out.println(newYork); // Output: New York: 8491079    } }            

Listing seven declares a City class with name and population fields. When a Urban center object is created, the City(String name, int population) constructor is called to initialize these fields to the chosen constructor'southward arguments. (I've likewise overridden Object'southward public String toString() method to conveniently render the city proper name and population value as a cord. Organization.out.println() ultimately calls this method to return the object'south string representation, which information technology outputs.)

Before the constructor is called, what values do name and population contain? You can observe out past inserting System.out.println(this.name); System.out.println(this.population); at the starting time of the constructor. Afterward compiling the source lawmaking (javac Urban center.coffee) and running the application (java City), y'all would observe zip for name and 0 for population. The new operator zeroes an object'south object (case) fields before executing a constructor.

As with class fields, you tin explicitly initialize object fields. For example, you lot could specify String name = "New York"; or int population = 8491079;. However, there'southward normally nothing to gain by doing this, because these fields will be initialized in the constructor. The simply do good that I can think of is to assign a default value to an object field; this value is used when you call a constructor that doesn't initialize the field:

              int numDoors = 4; // default value assigned to numDoors  Car(String make, String model, int year) {    this(brand, model, year, numDoors); }  Car(String make, Cord model, int twelvemonth, int numDoors) {    this.brand = make;    this.model = model;    this.year = year;    this.numDoors = numDoors; }            

Object initialization mirrors class initialization