Home | JSP | EJB | JDBC | Java Servlets | WAP  | Free JSP Hosting  | Spring Framework | Web Services | BioInformatics | Java Server Faces | Jboss 3.0 tutorial | Hibernate 3.0 | XML
 
 
Hot Web Programming Job

 

Tutorial Categories: Ajax | Articles | JSP | Bioinformatics | Database | Free Books | Hibernate | J2EE | J2ME | Java | JavaScript | JDBC | JMS | Linux | MS Technology | PHP | RMI | Web-Services | Servlets | Struts | UML


 

Search Host

Monthly Fee($)
Disk Space (MB)
Register With us for Newsletter!
Visit Forum! Post Questions!
Jobs At RoseIndia.net!

Have tutorials?
Add your tutorial to our Java Resource and get tons of hits.

We offer free hosting for your tutorials. and exposure for thousands of readers. drop a mail
roseindia_net@yahoo.com
 
   

Tutorials

Java Server Pages

JAXB

Java Beans

JDBC

MySQL

Java Servlets

Struts

Bioinformatics

Java Code Examples

Interview Questions

 
Join For Newsletter

Powered by groups.yahoo.com
Visit Group! Post Questions!

Web Promotion

Web Submission

Submit Sites

Manual Submission?

Web Promotion Guide

Hosting Companies

Web Hosting Guide

Web Hosting

Linux

Beginner Guide to Linux Server

Frameworks

Persistence Framework

Web Frameworks

Free EAI Tools

Web Servers

Aspect Oriented Programming

Free Proxy Servers

Softwares

Adware & Spyware Remover

Open Source Softwares

Anonymous Inner Classes

       

2000-12-07 The Java Specialists' Newsletter [Issue 002] - Anonymous Inner Classes

Author: Dr. Heinz M. Kabutz

If you are reading this, and have not subscribed, please consider doing it now by going to our subscribe page. You can subscribe either via email or RSS.


Welcome to the second "The Java(tm) Specialists' Newsletter", a low-volume newsletter that is aimed at in-the-trenches Java programmers and those interested in what the trenches look like nowadays. According to the latest Computing SA, the e-commerce industry in South Africa is struggling to take off because it is almost impossible to find Java programmers with any real experience. Germany seems to be experiencing a similar trend so they want to import 30'000 Indians. Aren't we working in an exciting segment of the IT market? I'm so glad I was too jung to try cash in on Y2K bugs and instead invested my time learning more of Java.

You are either on my mailing list because you begged to be added or because you did not beg to be removed, in either case, I hope you are enjoying reading this information and that it will be of benefit to you. Please let me know if there are topics that you would like discussed or if you would like to share some of your own experiences through this newsletter. This newsletter is distributed free of charge to anyone interested, so please forward it to friends and colleagues who might find the information in this newsletter useful.

In the last newsletter I mentioned in the non-kosher section that Java makes provision for more than one GUI thread to be in the system and that I did not know if/when this feature was used. So far I have not found out what the purpose of this is or if it is still used, although I suspect it's a leftover from the Awful Windows Toolkit. Do we have a Swing expert in the house?

Anonymous Inner Classes

A feature that we did not have in the early days of Java, when all you needed to run the VM was a 80386 with 4 MB RAM and a correctly set CLASSPATH, was the concept of the inner class, specifically the anonymous inner class (heck, we didn't need that newly-fangled fancy stuff then - we were real programmers ;-). Inner classes have made it possible to code with less lines and in the process to obscure the code to the unenlightened but make it wonderfully elegant to those who understand. A good friend and colleague told me "One good Java programmer is better than ten bad Java programmers" which I wholeheartedly agreed with. He then went on to say "And five bad Java programmers are better than ten bad Java programmers". Inner classes have widened this divide. The typical way of using anonymous inner classes is for writing GUI event handlers, e.g.

button.addActionListener(new ActionListener() {
  // This is how you define an anonymous inner class
  public void actionPerformed(ActionEvent e) {
    System.out.println("The button was pressed!");
  }
});

The amazing thing is that we are actually defining a new class(!) while calling another method. You can virtually make new classes in all sorts of places in Java. All of this is old hat to most of you, but last week I found a new application of anonymous inner classes that I had not thought of before. But first a diversion:

A lot of books seem to suggest that if you want to create a Thread in the middle of your code you do it as shown in this code. The example is typically known as an "idiot counter", patented by Microsoft ;-), in which they make the user dream that progress is happening by changing the screen output in some way..... (I have used this technique quite successfully in the past)

new Thread(new Runnable() {
  public void run() {
    try {
      while (true) {
        sleep(1000); System.out.print(".");
      }
    }
    catch(InterruptedException ex) {}
  }
}).start();

If we look at the definition of Thread we see that it takes a Runnable as a parameter so it sort-of makes sense to create an anonymous inner class from Runnable and stick that into the parameter. However, looking more carefully inside Thread we notice that the run() method defined in Thread calls the run() method defined in Runnable, if a Runnable has been passed into the Thread constructor. Instead, it would be more efficient to do the following, because we would have one less object on the heap and one less method call per Thread creation:

new Thread() {
  public void run() {
    try {
      while (true) {
        sleep(1000); System.out.print(".");
      }
    }
    catch(InterruptedException ex) {}
  }
}).start();

This way Thread itself is made into an anonymous inner class and we override the run() method so instead of Thread.run() having to check that a Runnable exists we can just execute the code in run(). It is a very small difference and I don't know why I have not seen it used before, but I suspect one of the early Java 1.1 lemmings jumped over the cliff holding a placard containing the Runnable as a parameter and all the other lemmings followed the sign ;-) To me the difference is more conceptual than actual and leads me on to the next application of inner classes:

Anyway, I now get to the real reason for another newsletter, which is an application of anonymous inner classes which I find quite useful. In Java 1.0, when we had to pass an array as a parameter to a method we did it as follows:


String[] temp_names = new String[3];
temp_names[0] = "Heinz";
temp_names[1] = "John";
temp_names[2] = "Anton";
universityRegistration.addNames(temp_names);

or, alternatively

String[] temp_names = { "Heinz", "John", "Anton" };
universityRegistration.addNames(temp_names);

In Java 1.1, SUN sneaked in a new construct so we would not need to have a temporary variable, which according to the Refactoring folklore is bad. Since JDK 1.1 we could thus say:

universityRegistration.addNames(
  new String[] { "Heinz", "John", "Anton" });

If you wanted to pass in a Collection instead of an array it would look as follows:

Collection temp_names = new Vector(3);
temp_names.add("Heinz");
temp_names.add("John");
temp_names.add("Anton");
universityRegistration.addNames(temp_names);

The ability to avoid local temporary variables with arrays was always a strong deciding factor in defining interfaces to my classes because I could get away with one line of code instead of five, and the less lines of code the better. I would therefore rather define addNames(String[] names) than addNames(Collection names) even if it meant I would have to convert backwards and forwards between arrays and collections. However, with anonymous inner classes we can get the same effect seen above but with collections:

universityRegistration.addNames(new Vector(3)
  {{ add("Heinz"); add("John"); add("Anton"); }});

How does work? Very simple, say we wanted to extend Vector with our own Vector, called MyVector, that contains the three elements "Heinz", "John", "Anton":

public class MyVector extends Vector {
  public MyVector() {
    super(3); // to initialise it with a size of 3
    add("Heinz"); add("John"); add("Anton");
  }
}

The call to the super constructor always happens first, so we could re-write MyVector as follows without changing the functionality in any way:

public class MyVector extends Vector {
  { // initializer block
    add("Heinz"); add("John"); add("Anton");
  }
  public MyVector() {
    super(3); // to initialise it with a size of 3
  }
}

If we want to make an instance of an anonymous inner class we can pass the parameters directly to the super class via the parameter list of the constructor of the anonymous class. In addition, any init block denoted by {} is done AFTER the call to the super class constructor is completed, so the class MyVector could look like this:

Vector myVector =
  new Vector(3) { // defining anonymous inner class
  {
    add("Heinz"); add("John"); add("Anton");
  }
};

From here the step to addNames(new Vector(3) {{ add("Heinz"); add("John"); add("Anton"); }}); is quite simple, I've just removed the comment and bunched the curly brackets together.

The thing that amazes me most about this "discovery" is that it is such an obvious thing to do if you have to pass a collection into a method and you know the size and elements of the collection, but in 3.5 years of Java I'd never thought of it, and I bet it does not occur anywhere in the 570'000 lines of JDK 1.3 code or the mega-project I worked on in South Africa.

---
Warning Advanced:
When you access private data members of the outer class, the JDK compiler creates package-access member functions in the outer class for the inner class to access the private members. This firstly leaves a security hole, although all data members in Java are public to the initiated ;-), and secondly used to impede performance before hotspot came along. So, if you are writing code that has to run reasonably well on non-hotspot code it would be better for performance reasons to make data members accessed by inner classes package-access.
---

As always, I welcome your comments and thank you for the positive feedback from last week.

With regards

Heinz


This material from The Java(tm) Specialists' Newsletter by Maximum Solutions (South Africa). Please contact Maximum Solutions for more information.

       

Useful Links
  JDO Tutorials
  EAI Articles
  Struts Tutorials
  Java Tutorials
  Java Certification

Tell A Friend
Your Friend Name
Search Tutorials

 

 
 
Browse all Java Tutorials
Java JSP Struts Servlets Hibernate XML
Ajax JDBC EJB MySQL JavaScript JSF
Maven2 Tutorial JEE5 Tutorial Java Threading Tutorial Photoshop Tutorials Linux Technology
Technology Revolutions Eclipse Spring Tutorial Bioinformatics Tutorials Tools SQL
 

Home | JSP | EJB | JDBC | Java Servlets | WAP  | Free JSP Hosting  | Search Engine | News Archive | Jboss 3.0 tutorial | Free Linux CD's | Forum | Blogs

About Us | Advertising On RoseIndia.net

Send your comments, Suggestions or Queries regarding this site at roseindia_net@yahoo.com.

Copyright © 2007. All rights reserved.