Newsletter sign-up
View all newsletters

Enterprise Java Newsletter
Stay up to date on the latest tutorials and Java community news posted on JavaWorld

Sponsored Links

Optimize with a SATA RAID Storage Solution
Range of capacities as low as $1250 per TB. Ideal if you currently rely on servers/disks/JBODs

Class and object initialization

Learn how to prepare classes and objects for use in an executing program

  • Print
  • Feedback

Page 5 of 9

Listing 6. ClassInitializationDemo4.java

// ClassInitializationDemo4.java
import java.io.*;
class ClassInitializationDemo4
{
   static String [] filenames;
   static
   {
      System.out.println ("Acquiring filenames");
      filenames = new File (".").list ();
      System.out.println ("Filenames acquired");
   }
   public static void main (String [] args)
   {
      System.out.println ("Displaying filenames\n");
      for (int i = 0; i < filenames.length; i++)
           System.out.println (filenames [i]);
   }
}


ClassInitializationDemo4 declares a filenames array field variable and then introduces a class block initializer. That initializer displays a status message, obtains a list of all filenames for those files that appear in the current directory, and displays a second status message. All that activity takes place before the main() method executes. When main() executes, a status message displays, along with a list of filenames. The result resembles the following output:

Acquiring filenames
Filenames acquired
Displaying filenames
ClassInitializationDemo4.java
ClassInitializationDemo4.class


In addition to placing the class field initializers' byte code instructions in a class's <clinit> method, the compiler places the byte code instructions of each encountered class block initializer in that same method. The compiler places these instructions in the <clinit> method according to a specific order. Because the compiler compiles a class in a top-to-bottom fashion, it places in the <clinit> method, in a top-to-bottom order, the equivalent byte code instructions to each encountered class field initializer and class block initializer. Refer back to Listing 6: The compiler places the class block initializer's byte code instructions in ClassInitializationDemo4's <clinit> method. If that class specified a class field initializer for its filenames class field, the byte code instructions comprising that class field initializer would appear before the class block initializer's byte code instructions in the <clinit> method.

After studying ClassInitializationDemo4's source code, you might wonder how useful class block initializers are. After all, you could easily move all code from ClassInitializationDemo4's class block initializer to its main() method. Nevertheless, class block initializers are useful. For example, Sun's JDBC (Java Database Connectivity) API uses class block initializers to simplify database driver registration. Consider the following code fragment:

Class.forName ("sun.jdbc.odbc.JdbcOdbcDriver");      


The code fragment calls Class's forName() method to load the JdbcOdbcDriver class (located in the sun.jdbc.odbc package). Once that code fragment completes, the class loads, and the database driver associated with the JdbcOdbcDriver class registers with JDBC. What causes that registration to occur? The answer is Java statements that comprise JdbcOdbcDriver's class block initializer. (I have more to say about JDBC in a future article.)

When working with class block initializers, keep in mind two more items: First, any variable that you declare in a class block initializer is local to that block. No code outside the block can access the variable. Second, Java permits you to declare a constant class field without a class field initializer as long as you explicitly initialize that constant in a class block initializer. Furthermore, within the class block initializer, you must initialize the constant before you attempt to read its value. Listing 7 illustrates both points:

  • Print
  • Feedback

Resources