Anonymous inner classes of Java are called anonymous because they have no name. They are anonymous and inline. Anonymous classes are essentially inner classes and defined within some other classes. However, the way anonymous classes are written in Java code may look weird but anonymous inner classes facilitate programmers to declare and instantiate the class at the same time. Another important point to note about anonymous inner classes is that they can be used only once on the place they are coded. In other words, if you want to create only one sub-classed object of a class, then you need not to give the class a name and you can use anonymous inner class in such a case. Anonymous inner classes can be defined not just within a method, but even within an argument to a method. Anonymous inner classes cannot have explicit constructors declared because they have no name to give the constructor.
Anonymous inner classes are defined at the same time they are instantiated with new
. They are not declared as local classes are done rather anonymous inner classes are defined in the new
expression itself, as part of a statement. An anonymous inner class declaration expression looks like a constructor invocation, except that there is a class definition contained in a block of code.
Before going into further details of anonymous inner classes we must understand that an anonymous inner class is not an independent inner class rather it is a sub-class of either a class type or an anonymous implementer of the specified interface type. So, when anonymous inner classes are in picture polymorphism must be there. And when polymorphism is there you can only call methods from parent class reference those are defined in the reference variable type. Java's anonymous inner classes being sub-classes or implementers do strictly adhere to the polymorphism rules.
Let's take an example of seemingly strange looking syntax that defines an anonymous inner class. In following example code, the Dog
reference variable dog
refers not to an instance of Dog
but to an instance of an anonymous inner subclass of Dog
.
/* AnonymousClassDemo.java */ public class AnonymousClassDemo { public static void main(String[] args) { Dog dog = new Dog() { public void someDog () { System.out.println("Anonymous Dog"); } }; // anonymous class body closes here //dog contains an object of anonymous subclass of Dog. dog.someDog(); } } class Dog { public void someDog() { System.out.println("Classic Dog"); } }
In above piece of code; see the code line Dog dog = new Dog() {
, there is a brace at the end of line, not a semicolon. This curly brace opens the class definition and declares a new class that has no name (anonymous class). Now let's enter into the body of newly defined subclass of class Dog
and you will see that someDog()
is being overridden. This is the crux of defining an anonymous inner class because we want to override one or more methods of the super class on the fly.
Remember, anonymous inner classes are inherited ones, and we always use a superclass reference variable to refer to an anonymous subclass object. And, we can only call methods on an anonymous inner class object that are defined in the superclass. Though, we can introduce new methods in anonymous inner class, but we cannot access them through the reference variable of superclass because superclass does not know anything about new methods or data members introduced in subclass.
It would be interesting to know that you can also create an anonymous inner class for an interface type. Magically you can also pass anonymous inner class as an argument to a method. We will talk of them in subsequent sections.
In previous example as we have created an anonymous inner class for a class type. Likewise, an anonymous inner class can implement an interface anonymously. Here is an example.
/* AnonymousInterfaceDemo.java */ interface Manageable { public void manage(); } public class AnonymousInterfaceDemo { public static void main(String[] args) { Manageable m = new Manageable() { public void manage() { System.out.println("It is manageable"); } }; // anonymous interface implementer closes here //m contains an object of anonymous interface implementer of Manageable. m.manage(); } }
The above code, like the Dog
example, still creates an instance of anonymous inner class, but this time the new just-in-time class is an implementer of the Manageable
interface. You would have also noticed the unusual but perfectly valid syntax Manageable m = new Manageable() {
, where Manageable
is an interface rather than a non-abstract class type. The code looks like instantiating a Manageable
object but that is not so. It is creating an instance of a new, anonymous implementer of Manageable
.
It is very important to note about anonymous inner classes that anonymous inner classes can either implement an interface or extend a class, they can't do both at the same time. There is no such mechanism by which an anonymous inner class can implement multiple interfaces. An anonymous inner class can't even extend a class and implement an interface at the same time.
Anonymous inner classes in method arguments become handy and very useful when it comes to event handling in Java Swing, which is GUI model Java follows. Following is a trivial example acquaints you to the syntax of anonymous inner classes in method arguments.
/* MethodArgumentAnonymousClassDemo.java */ interface Manageable { public void manage(); } class Manager { public void canManage(Manageable m) { m.manage(); } } public class MethodArgumentAnonymousClassDemo { public static void main(String[] args) { Manager m = new Manager(); m.canManage (new Manageable () { public void manage() { System.out.println("Yes, it is being anonymously managed!"); } }); // anonymous interface implementer as method argument closes here } }
If you read the above example carefully, you would see that there is no class that implements Manageable
, therefore, you can't create an instance and assign it to Manageable
reference. So, you first need a class that implements Manageable
, and then you need an instance of that class to pass to the Manager
class's canManage()
method. If this is needed only once, you can simply define an anonymous inner class right inside the argument. That's all, the above example demonstrates about anonymous inner classes in method arguments.
Many programmers may not like anonymous inner classes because they add complexity to the code. But they have been proved useful in some cases and give programmers facility to define a brand new sub class in an expression. Anonymous inner classes are handy when you want to define callbacks without writing a lot of code such as enumerations, iterators, visitors, etc. Anonymous inner classes are also helpful for adding behaviour to objects which already have names, such as AWT components (to which anonymous event handlers are added), and threads.
Here is a trivial application example of use of Anonymous inner classes. To understand the following piece of code you would require a little knowledge of Java Swing, which is GUI model Java follows. But our real motto is to demonstrate the use of anonymous inner classes in designing event handlers or action listeners. Have a look at following code and in line comments to get an insight. I prepared this example to show you more realistic use case of anonymous inner classes.
/* AnonymousClassAppUseDemo.java */ import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.BoxLayout; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; public class AnonymousClassAppUseDemo { public static void main(String[] args) { GreetingFrame hwf = new GreetingFrame(); hwf.CreateFrame(); } } class GreetingFrame { private JFrame frame; private JPanel messagePanel; private JPanel buttonPanel; private JPanel container; private JLabel messageLabel; private JButton greetButton; private JButton clearButton; public GreetingFrame () { //beautify the frame JFrame.setDefaultLookAndFeelDecorated(true); frame = new JFrame("Hello World"); messagePanel = new JPanel(); //used to place greeting message buttonPanel = new JPanel(); //used to place command button container = new JPanel(); //used to place message and button Panels messageLabel = new JLabel(" "); // contain greeting message greetButton = new JButton("Greeting"); //display greeting message when clicked clearButton = new JButton("Clear"); //clears greeting message when clicked } public void CreateFrame () { frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); container.setLayout(new BoxLayout(container, BoxLayout.Y_AXIS)); messagePanel.add(messageLabel); buttonPanel.add(greetButton); buttonPanel.add(clearButton); /* brand new class of super type ActionListener * will be created anonymously and passed to addActionListener method * of greetButton object */ greetButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { messageLabel.setText("Hello User! Greetings of the day!"); } }); /* brand new class of super type ActionListener * will be created anonymously and passed to addActionListener method * of clearButton object */ clearButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { messageLabel.setText(" "); } }); container.add(messagePanel); container.add(buttonPanel); frame.getContentPane().add(container); //Display the window. frame.setSize(300, 200); frame.setLocationByPlatform(true); frame.setVisible(true); } }
Above piece of code generates the following GUI and demonstrates you the use of anonymous inner classes, the motivation was not to create a great user interface but to show you that the actions performed on click events of "Greeting" and "Clear" buttons are implemented by using anonymous inner classes.
This tutorial explained Java's anonymous inner classes and their application uses. Hope you have enjoyed reading this tutorial. Please do write us if you have any suggestion/comment or come across any error on this page. Thanks for reading!
Share this page on WhatsApp