Shrinking Source Code: Java initialization
Saturday, October 20th, 2007There have been a few discussions on how to do a particular task with the smallest amount of “code”. Some people talk about this with regards to soure code, and others with regards to object (a.k.a machine-instructions or byte code). While the later has some actual application, its often more “fun” to talk about the former.
Shrinking source code down for no other reason is generally bad practice, but it is an interesting exercise. I think that in this article we can distill the basic concept down to what is the smallest valid (in characters) Java source file that will compile, and when run does absolutely nothing.
For our first attempt, lets try the straight-forward approach. Not bending any rules.
class C{public static void main(String[]a){}}
That is 45 characters long. This compiles (javac C.java) and executes (java C) .Nothing spectacular, and there doesn’t appear to be anything superfluous there, but I assure you there is.
Think back to the JLS. Specifically, before the JVM can execute main() on a class, it must initialize it first (JLS 12.4.1).This gives use another way to execute code.
class C{static {} public static void main(String[]a){}}
This is a little longer, but bear with me. It still compiles and executes, just like our previous versions. What about removing main now?
class C{static{}}
This is indeed very short, and compiles just fine, but unfortunately we get Exception in thread “main” java.lang.NoSuchMethodError: main. Well, that doesn’t exactly do nothing, which is what our goal is. Note that we can put code into the static initializer.
class C{static{System.exit(0);}}
Now we’re down to 32 characters, and it compiles and does nothing. Sweet. What happens is that the JVM executes the static initializer before looking for the main method. The initializer tells the JVM to terminate (JLS 12.8), so it complies. Hence, no exception.
Is there anything else we can rid ourselves of? With the advent of Enums in Java 5, the answer is yes! We don’t need to explicitly create a static initializer, because enums will do that for us.
enum C{A;{System.exit(0);}}
27 charecters long, and it compiles and does nothing. Amazing. So what’s happening here? Enum types in Java are actually classes. Furthermore, they are singletons. In this case, the compiler creates two classes. C extends Enum, and A extends C. When we run java C, the JVM loads the class C which has a static initializer that sets C.A = new A(), which starts the instance initialization (JLS 12.5) process. Part of this process is to call the initializer of the parent class (in this case C). We added an instance initializer in C which kills the JVM.
So there you have it. The smallest possible Java program which does absolutely nothing (as far as I know). When trying to create the smallest possible Java program which does something, you would probably be wise to start from this template, unless you find a tricky way of having existing library code closing the JVM after doing your bidding otherwise. Not terribly useful, but somewhat entertaining, and it might help give you a better understanding of what goes on under the hood.
As with most of my esoteric Java features, don’t try this in production code.
