Could you explain this code to me please?
Hi,
In my simple JFrame window application I have the following code:
Code :
exitItem.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
System.exit(0);
}
});
I know what it is doing, it is making it so that when I click on the JMenuItem object named exitItem it terminates the application. Im just having trouble understanding how it works exactly.
I know by calling the addActionListener method of the exitItem object I am adding a action listener to the object.
The thing which I am confused on is with the methods parameter. I can in the parameter we are creating an action listener, i am not sure why. Ive also never seen an object being created followed by curly braces?
Could someone give me a walkthrough of whats happening, i know its alot to ask.
Re: Could you explain this code to me please?
If I'm understanding your question correctly, you're asking about the anonymous inner class there. That term is a good place to start a google search, but here's an article explaining your example almost exactly: JavaRanch Campfire - Getting in Touch with your Inner Class
Re: Could you explain this code to me please?
Hmm. Could you answer my few questions?
1. Am i right in thinking that the parameter of the addActionListener method has to be an ActionListener object which defines what to do when the item is used?
2. In my code, when I put "(new ActionListener(){code})" I am creating an ActionListener object with no name?
3. After I have created the ActionListener object which has no name, by putting an opening curly brace after it I can define the object?
4. Is it a Java rule that when we create an object, for example "Class object = new Class();", if we was to put "{}" after creating it then the code inside the curly braces would be defining the object?
Re: Could you explain this code to me please?
Quote:
Originally Posted by
TP-Oreilly
Hmm. Could you answer my few questions?
I can try.
Quote:
Originally Posted by
TP-Oreilly
1. Am i right in thinking that the parameter of the addActionListener method has to be an ActionListener object which defines what to do when the item is used?
It has to be an ActionListener. Note that ActionListener is an interface, so the actual instance is going to be a class that implements ActionListener, or a class that inherits from something that implements ActionListener. The anonymous inner class is basically doing that behind the scenes.
Quote:
Originally Posted by
TP-Oreilly
2. In my code, when I put "(new ActionListener(){code})" I am creating an ActionListener object with no name?
Yep. That's why it's called anonymous. No name.
Quote:
Originally Posted by
TP-Oreilly
3. After I have created the ActionListener object which has no name, by putting an opening curly brace after it I can define the object?
Sort of. You can define the methods within that Object. You can override a method from the super class (such as actionPerformed), or you can declare new methods, just like you were in a non-anonymous class.
Quote:
Originally Posted by
TP-Oreilly
4. Is it a Java rule that when we create an object, for example "Class object = new Class();", if we was to put "{}" after creating it then the code inside the curly braces would be defining the object?
Again, sort of. The code inside the curly braces can define methods (or variables, members in general) in that anonymous subclass.
Re: Could you explain this code to me please?
Thanks very much for the help, both in this thread and the others :)
The thing what threw me was the curly braces after creating the object because ive never seen object creation followed by curly braces before.
Re: Could you explain this code to me please?
Quote:
Originally Posted by
TP-Oreilly
Thanks very much for the help, both in this thread and the others :)
The thing what threw me was the curly braces after creating the object because ive never seen object creation followed by curly braces before.
Yeah, that syntax can take some getting used to. But it's just an anonymous inner class. Once you know how they work, you'll start using them all the time.
Re: Could you explain this code to me please?
One last thing, you said:
"It has to be an ActionListener. Note that ActionListener is an interface, so the actual instance is going to be a class that implements ActionListener, or a class that inherits from something that implements ActionListener. The anonymous inner class is basically doing that behind the scenes."
Where you said " so the actual instance is going to be a class that implements ActionListener", so the compiler creates a un-named class and implements the ActionListener?
Re: Could you explain this code to me please?
Quote:
Originally Posted by
TP-Oreilly
One last thing, you said:
"It has to be an ActionListener. Note that ActionListener is an interface, so the actual instance is going to be a class that implements ActionListener, or a class that inherits from something that implements ActionListener. The anonymous inner class is basically doing that behind the scenes."
Where you said " so the actual instance is going to be a class that implements ActionListener", so the compiler creates a un-named class and implements the ActionListener?
Quite probably. You can test this out yourself. I created this class:
Code java:
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class InnerClassTest {
public static void main(String... args){
ActionListener al = new ActionListener(){
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("Just testing.");
}
};
}
}
When I compiled it, I saw two .class files, InnerClassTest.class and InnerClassTest$1.class
Here is InnerClassTest.class:
Code java:
// Compiled from InnerClassTest.java (version 1.6 : 50.0, super bit)
public class InnerClassTest {
// Method descriptor #6 ()V
// Stack: 1, Locals: 1
public InnerClassTest();
0 aload_0 [this]
1 invokespecial java.lang.Object() [8]
4 return
Line numbers:
[pc: 0, line: 4]
Local variable table:
[pc: 0, pc: 5] local: this index: 0 type: InnerClassTest
// Method descriptor #15 ([Ljava/lang/String;)V
// Stack: 2, Locals: 2
public static void main(java.lang.String... args);
0 new InnerClassTest$1 [16]
3 dup
4 invokespecial InnerClassTest$1() [18]
7 astore_1 [al]
8 return
Line numbers:
[pc: 0, line: 6]
[pc: 8, line: 12]
Local variable table:
[pc: 0, pc: 9] local: args index: 0 type: java.lang.String[]
[pc: 8, pc: 9] local: al index: 1 type: java.awt.event.ActionListener
Inner classes:
[inner class info: #16 InnerClassTest$1, outer class info: #0
inner name: #0, accessflags: 0 default]
}
And here is InnerClassTest$1.class:
Code java:
// Compiled from InnerClassTest.java (version 1.6 : 50.0, super bit)
class InnerClassTest$1 implements java.awt.event.ActionListener {
// Method descriptor #8 ()V
// Stack: 1, Locals: 1
InnerClassTest$1();
0 aload_0 [this]
1 invokespecial java.lang.Object() [10]
4 return
Line numbers:
[pc: 0, line: 6]
[pc: 4, line: 1]
Local variable table:
[pc: 0, pc: 5] local: this index: 0 type: new InnerClassTest(){}
// Method descriptor #17 (Ljava/awt/event/ActionEvent;)V
// Stack: 2, Locals: 2
public void actionPerformed(java.awt.event.ActionEvent e);
0 getstatic java.lang.System.out : java.io.PrintStream [18]
3 ldc <String "Just testing."> [24]
5 invokevirtual java.io.PrintStream.println(java.lang.String) : void [26]
8 return
Line numbers:
[pc: 0, line: 9]
[pc: 8, line: 10]
Local variable table:
[pc: 0, pc: 9] local: this index: 0 type: new InnerClassTest(){}
[pc: 0, pc: 9] local: e index: 1 type: java.awt.event.ActionEvent
Inner classes:
[inner class info: #1 InnerClassTest$1, outer class info: #0
inner name: #0, accessflags: 0 default]
Enclosing Method: #37 #39 InnerClassTest.main([Ljava/lang/String;)V
}
So you see, InnerClassTest$1.class is the compiled version of the anonymous inner class, and it does indeed implement ActionListener.
However, I don't think that behavior is guaranteed. It's probably best not to worry too much about the inner workings.
Re: Could you explain this code to me please?