Skip to Content

Recently I came upon a issue where an application provider tried to use inner classes in

What is an inner class?

First let’s define what inner class is. Inner class is a class which definition is inside other class. They are also called

nested classes

. Inner classes can be static and non-static. This is a huge difference, because they are instantiated differently.

a) static inner classes(nested top-level classes) – they are instantiated in the same way as all top-level classes:


public class Outer {
public static class StaticNested{
public String getMessage(){
return "Hello, I'm static nested class.";
}
}

public static void main(String[] args) {
StaticNested nested = new Outer.StaticNested();
System.out.println(nested.getMessage());
}
}

The only tricky section here is that we put the name of the wrapper class using it as a package declaration. During instantiation the public, non-static constructor, that the compiler creates implicitly, is used. Note that no instance of class Outer is created.

b) Non-static inner classes – they receive implicitly constructor that takes reference to an instance of the outer class and therefore doesn’t have no-arg constructor.


public class Outer {
public class Inner{
public String getMessage(){
return "Hello, I'm inner class.";
}
}
}


public class Client {
public static void main(String[] args) {
Outer outer = new Outer();
Outer.Inner inner = outer.new Inner();
System.out.println(inner.getMessage());
}
}

Here you see that in order to instantiate inner class you need an instance of the outer class.
The only constructor that the compiler created for class “Outer$Inner” is:

public Outer$Inner(Outer)

Problem

In case you want to use Java EE components as inner classes  (where the container is responsible for their   lifecycle),  we face the following problems during instantiation of the inner classes:

– when an instance of inner class is being created , the container must create an empty, useless instance of the outer class. This leads to performance-related problems such as CPU time and memory consumption.

– Using an inner class as JavaEE component is a design flaw, because of the useless instance created.

– $ is a legal java identifier. You can have it in the name of inner class. Then it is complicated to understand which is the inner class if you declare this as a servlet in the web descriptor, for example “My$House$Has$Lots$of$Rooms”.

– to make things worse, one could make a hierarchy of inner classes. It is perfectly legal to have nested inner classes on several levels. Combine this with the previous issue and you may get the idea.

Resolution

The JavaEE components’ specifications have mentioned as several occasions  that the constructors should be public and must have no argument constructor. For example here are excerpts from the servlet and JSP specifications :

To report this post you need to login first.

Be the first to leave a comment

You must be Logged on to comment or reply to a post.

Leave a Reply