473,569 Members | 2,669 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Class Initializers

13,262 MVP
Inspiration

Inspired by a post by Jos in the Java forum, I have put together a little article on class initializers.
Initializers are indeed underutilized by most Java programmers. Once the Java programmer knows about the constructor he/she feels they have found a good place to put code that must be run before an object is created and sometimes don't try to look for more places to put pre-object creation code. The other places to put pre-object creation code are initializers.

There are two types of initializers that can be used in classes. Static initializers and instance initializers.


Static initializers.

Static initializers are the first bit of code that is run once when the class is being loaded. Since they are static, they are not tied to any particular instance but rather are shared among all objects of their class. An instance initializer block is thus executed only once (during class loading). After that, creation of objects in the program do not trigger execution of the static initializer block again. Another consequence of being static is that you can only use static initializers to initialize static variables. This makes sense because these are the only ones available during class loading. Enough chattering, let's dive into an example:

A scenario

The scenario is a Utility class that gives information about products in a database. The class works on a list of all the products in the database by loading them into an arraylist once when the class is loaded and then referring to that arraylist on all subsequent inquiries on products. The exists method for example, does not need to connect to the database but just queries the products ArrayList.

Disclaimer

Please note that this example is for illustration purposes only. This approach is only helpful in a read only database system because if a product is added into the database during this program's execution after the ProductUtils class has been loaded, then that product will not be available in the list of products created at class loading. There are workarounds of course but we digress ...

A static initializer block is simply denoted by a pair of opening and closing braces preceeded by the static keyword with the initialization code placed inside the braces
Expand|Select|Wrap|Line Numbers
  1.  static {
  2. //initialization code goes here.
Here it is in action
Expand|Select|Wrap|Line Numbers
  1. import java.sql.Connection;
  2. import java.sql.DriverManager;
  3. import java.sql.ResultSet;
  4. import java.sql.Statement;
  5. import java.util.ArrayList;
  6. import java.util.List;
  7. class ProductUtils {
  8.     static List<Product> products = new ArrayList();
  9.     static {
  10.         try {
  11.             Class.forName("com.mysql.jdbc.Driver");
  12.             Connection con = DriverManager.getConnection("jdbc:mysql://localhost/test","r035198x ", "acomplexpassword");
  13.             Statement st = con.createStatement();
  14.             ResultSet rs = st.executeQuery("select * from Products");
  15.             while(rs.next()) {
  16.                 products.add(new Product(rs.getInt(1), rs.getString(2)));
  17.                 System.out.println("product added");
  18.             }
  19.         }
  20.         catch(Exception e) {
  21.             e.printStackTrace();
  22.         }
  23.  
  24.     }
  25.  
  26.     public static void main(String[] args) {
  27.  
  28.     }
  29.  
  30.     boolean exists (Product product) {
  31.         return products.contains(product);
  32.     }
  33.  
  34. }

Output with a blank main


Running this program with the proper configurations (database created and connector set in the class path correctly) prints product added for each product that is added to the ArrayList of products. Note that I have deliberately left the main method blank but the program connects to the database, loads objects into an arraylist and prints some stuff to the console. The static initializer block is responsible for all this. The main method is innocent.
This should make it clear that an instance of a class is not required for a static initializer block to be executed. Static initializers can be as sophisticated as you wish, just keep in mind that they are executed during class loading and therefore can only access other statics.

The more the merrier?

You can have as many static initializers as you wish in your class. They will be executed in the order that they appear in your code (from the top of the file to the bottom). To make your code easy to read, you should put different tasks in different initializer blocks so that each block performs one logical operation.

Use

Use static initializers to perform operations that must be done once before all objects of a class are created. Doing these operations in a static initializer ensures that they are done once and therefore can speed up your program because it doesn't have to do them again every time an object of that class is created. More specifically, use static initializers for operations that must be done during class loading of that class by the JVM. The example above also contains a common use of static initializers.

A common use

The specs for the Driver interface say
When a Driver class is loaded, it should create an instance of itself and register it with the DriverManager. This means that a user can load and register a driver by calling
Class.forName(" foo.bah.Driver" )
Database driver writers are being told here that when their drivers are loaded, an object must be created and registered with the driver manager.

The MySQL driver that was used to connect to the database in the example above had to obey this rule. The call to DriverManager.r egisterDriver() was done in a static initializer of the MySQL driver class which looks something like:
Expand|Select|Wrap|Line Numbers
  1.   static {
  2.         try {
  3.             java.sql.DriverManager.registerDriver(new Driver());
  4.         } catch (java.sql.SQLException E) {
  5.             throw new RuntimeException("Can't register driver!");
  6.         }
  7.  
  8.         if (DEBUG) {
  9.             Debug.trace("ALL");
  10.         }
  11.     }
written by Mark Matthews

This is helpful since loading a driver now just translates to loading the driver class for that driver.

Instance initializers

The difference between static initializers and instance initializers is in the time that they are executed. While static initializers are executed once when a class is loaded, instance initializers are run once before an object is created. This changes matters somewhat. Instance initializers now have access to non-static variables in a class including the this object.
Instance initializers in named classes should be used to initialize instance variables which cannot be initialized using one line of code but should be initialized the same way for all the constructors in that class. Otherwise if the variable should be initialized differently depending on the constructor that was invoked, then it should be initialized in the appropriate constructors.

Expand|Select|Wrap|Line Numbers
  1.  class Cat {
  2.     String name;
  3.     int numOfLegs;
  4.     int numOfEars;
  5.  
  6.     {
  7.         numOfLegs = 2;
  8.         numOfEars = 2;
  9.     }
  10.     Cat(String name) {
  11.         this.name = name;
  12.     }
  13.     public String toString() {
  14.         return name + " has " + numOfLegs + " legs and " + numOfEars + " ears"; 
  15.     }
  16.  
  17.     public static void main(String[] args) {
  18.         System.out.println(new Cat("Mary").toString());
  19.  
  20.     }
  21. }
Here, every cat is initialised with two legs and two ears.

Called before constructors

Instance initializers are always called before a constructor is called (note that the compiler actually generates <init> methods for every constructor in a class and these are the ones called when a constructor is invoked). As with static initializers, multiple initializers are executed in their textual order.

Instance initializers in anonymous classes

When used with anonymous classes, initializers can make cumbersome code more elegant. Generally you want to isolate code that does different operations. Specifically you don't want to mix code that builds a structure (e.g list, map or more exotic structures) with code that manipulates that structure. Suppose you want to build a mapping between Integers and Strings so that 1 maps to “Sunday”, 2 maps to “Monday” etc.
You could build the map as
Expand|Select|Wrap|Line Numbers
  1.  Map<Integer, String> days = new HashMap();
  2. days.put(1, “Sunday”);
  3. days.put(2, “Monday”);
  4. //etc
After this then you start manipulating the map.

If an anonymous class and initializer is used, this can be done as
Expand|Select|Wrap|Line Numbers
  1.  Map<Integer, String> days = new HashMap() {
  2.             {
  3.                          put(1, “Sunday”);
  4.                  put(2, “Monday”);
  5.                          //etc
  6.                }
  7. };
  8.  
The closing }; in the code above clearly marks the end of the creation of the map. Anyone looking over the code can easily switch between checking code that creates the structure and code that manipulates the structure. This can save a few seconds of debugging time depending on the complexity of the initialization. Remember that the HashMap is just an example of a structure that may require several lines of initialization. Other user defined structures can also benefit, perhaps even more, from the same approach depending on the actions that must be done to fully initialize the structure.


Initializers and exceptions

Static initializers cannot throw checked exceptions (it is a compilation error if they do).
An instance variable initializer in a named class can only throw checked exceptions if that exception or one of its supertypes is explicitly declared in the throws clause of each constructor of its class and the class has at least one explicitly defined constructor.(JL S Third Edition[8.3.2]).

Expand|Select|Wrap|Line Numbers
  1.  static {
  2.     if(true) {
  3.         throw new Exception();
  4.     }
  5. }
does not compile.
while
Expand|Select|Wrap|Line Numbers
  1.  public class Sorry {
  2.     String sorry;
  3.     public Sorry() throws Exception{}
  4.         {
  5.         if(true) {
  6.                           throw new Exception();
  7.                     }
  8.     }
  9. }
compiles fine.

Instance variable initializers in anonymous classes, however, are allowed to throw any checked exceptions.
Expand|Select|Wrap|Line Numbers
  1.  import java.io.IOException;
  2. public class Sorry {
  3.     String sorry;
  4.     public Sorry() {}
  5.     public static void main(String[] args) throws IOException{
  6.         System.out.print( new Sorry() {
  7.             {
  8.        if(true) {
  9.                               throw new IOException("Sorry");
  10.                       }
  11.             }
  12.         }.toString());
  13.  
  14.     }
  15.     public String toString() {
  16.         return sorry;
  17.     }
  18.  
  19. }
compiles fine.

In case you are wondering about the name of the class, a friend of mine wrote a Sorry class to apologize 5 000 times to his girlfriend through email and I just stole that class and changed it a bit to suit more serious purposes.

I hope you have now some understanding on initializers and know when to use which one to better your programs in both speed and maintanability.
Dec 3 '07 #1
1 7317
ajos
283 Contributor
Class initializers

In case you are wondering about the name of the class, a friend of mine wrote a Sorry class to apologies 5 000 times to his girlfriend through email and I just stole that class and changed it a bit to suit more serious purposes.
Hi r035198x,
I was just scanning around this article of yours. Though i didnt read all of the things completely....t his one definitely was most funny :) . Funny because, the other day i had to face this very situation and had to say sorry some 200 times in my case(she's less demanding than your friend i guess :)). How the hell did you guys get this idea...coz it took me some time to type all the sorries :(. AnyWays great article. Kudos to you and TSDN.
regards,
ajos
Dec 6 '07 #2

Sign in to post your reply or Sign up for a free account.

Similar topics

4
23318
by: Doug | last post by:
Say I have a class with a constant in it. I also have a variable in that class that I would like to set to that constant as the initialization value. Why doesn't the following work? class Square { const DEFAULT_SIZE=5; var $size=self::DEFAULT_SIZE; // how do i set $size to DEFAULT_SIZE? }
106
5506
by: A | last post by:
Hi, I have always been taught to use an inialization list for initialising data members of a class. I realize that initialsizing primitives and pointers use an inialization list is exactly the same as an assignment, but for class types it has a different effect - it calls the copy constructor. My question is when to not use an...
6
3321
by: Neil Zanella | last post by:
Hello, I would like to know what the C standards (and in particular the C99 standard) have to say about union initializers with regards to the following code snippet (which compiles fine under gcc 3.2.2 but does not produce the expected results, the expected results being the ones annotated in the comments in the code): #include...
4
1710
by: John Devereux | last post by:
Hi, gcc has started warning about the lack of inner braces in initializers like :- struct io_descriptor { int number; char* description;
8
2337
by: Pent | last post by:
Hi All, Why is this code valid? How can the static ctor be used? It doesn't act as class ctor at all. struct A { static A() { } }
5
8723
by: Chris | last post by:
Hi, I don't get the difference between a struct and a class ! ok, I know that a struct is a value type, the other a reference type, I understand the technical differences between both, but conceptually speaking : when do I define something as 'struct' and when as 'class' ? for example : if I want to represent a 'Time' thing, containing...
10
2663
by: Ognen Duzlevski | last post by:
Hi, I have a "language definition" file, something along the lines of: page :: name : simple caption : simple function : complex function :: name : simple code : simple
37
3996
by: JohnGoogle | last post by:
Hi, Newbie question... After a recent article in VSJ I had a go at implementing a Fraction class to aid my understanding of operator overloading. After a previous message someone suggested that I implement it as a struct rather than a class which I did and all worked OK. The simplest declaration for the struct is:
3
2955
by: dischdennis | last post by:
Hello List, I would like to make a singleton class in python 2.4.3, I found this pattern in the web: class Singleton: __single = None def __init__( self ): if Singleton.__single: raise Singleton.__single
16
1503
by: shapper | last post by:
Hello, I have the following classes: namespace MyApp.Models { public class Tie { public Count Count { get; set; } public Tie() { this.Count = new Count(); }
0
7703
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main...
0
8139
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that...
1
7682
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For...
0
7984
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the...
0
5228
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert...
0
3663
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in...
1
2119
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
1
1230
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
0
954
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.