This post is in continuation to exploring little known features of java. In previous post, I have covered “Instances of same class can access private members of each other” and Some very surprising usage of class sun.misc.Unsafe. In this post, I am discussing about a little known feature of initializes blocks.
Initializers can be used in two ways:
1) Non static initializer block
It is dependent on the object and the initialization block is executed for each object of the class that is created. It can initialize instance member variables of the class.
2) Static initializer block
It is defined using the keyword static and is executed once when the class is loaded and has a restriction that it can only initialize static data members of the class.
This is what we all know. Now coming to part which many of us do not knew before.
Sometimes in initializer block you may need to write some code, which can throw checked exceptions. Checked exceptions are those exceptions which are checked at compile time and compiler force you to handle them in your code. Let’s take an example:
public class CheckedExceptionsFromConstrctor { Document doc = null; { doc = new SAXBuilder(false).build(new StringReader(new String("<users/>"))); } }
Above code throws two checked exceptions. IOException and JDOMException. You can handle them using try-catch. e.g.
{ try { doc = new SAXBuilder(false).build(new StringReader(new String("<users/>"))); } catch (JDOMException | IOException e) { e.printStackTrace(); } }
If you do not wish to handle exception in intializer and try to throw it, compiler will not allow you to this.
{ try { doc = new SAXBuilder(false).build(new StringReader(new String("<users/>"))); } catch (JDOMException | IOException e) { throw e; //Not allowed } }
Solution: Add throws clause in all constructors for all checked exceptions
Add the throws clause in constructors and you will be able to throw the checked exceptions from initializers. e.g.
public class CheckedExceptionsFromConstrctor { Document doc = null; public CheckedExceptionsFromConstrctor() throws IOException, JDOMException { //Some other code } public CheckedExceptionsFromConstrctor(String s) throws IOException, JDOMException { //Some other code } { doc = new SAXBuilder(false).build(new StringReader(new String("<users/>"))); } }
or
public class CheckedExceptionsFromConstrctor { Document doc = null; public CheckedExceptionsFromConstrctor() throws IOException, JDOMException { //Some other code } public CheckedExceptionsFromConstrctor(String s) throws IOException, JDOMException { //Some other code } { try { doc = new SAXBuilder(false).build(new StringReader(new String("<users/>"))); } catch (JDOMException | IOException e) { throw e; } } }
Above both solutions are valid and compiler will allow you do this this.
Static initializers cannot throw checked exceptions
The above reasoning was for non-static initializers. If you got static initializers in your class, then you MUST handle checked exceptions. You are not allowed to throw them in any possible way.
public class CheckedExceptionsFromConstrctor { static Document doc = null; public CheckedExceptionsFromConstrctor() { //Some other code } static { try { doc = new SAXBuilder(false).build(new StringReader(new String("<users/>"))); } catch (JDOMException | IOException e) { e.printStackTrace(); //You must handle the exception here } } }
That’s all around this topic. Hope you liked it. I will appreciate if you hare your thoughts in comments section. And do not forget to subscribe through email, for new updates next such little known features.
Happy Learning !!
Leave a Reply