I’m reading an article about inner class. I found an example that demonstrates anonymous inner class (mentioned below).
button1 = new JButton();
button2 = new JButton();
...
button1.addActionListener(
new java.awt.event.ActionListener()
{
public void actionPerformed(java.awt.event.ActionEvent e)
{
// do something
}
}
);
According to the example it creates an inner class for responding to a button using ActionListener interface. As I know an interface does not have a constructor. But I’m wondering, how they call a constructor.
"new java.awt.event.ActionListener(){
}"
An interface does not have a constructor, but an anonymous class does: like all classes, it extends java.lang.Object implicitly, therefore it can call the Object's parameterless constructor.
Moreover, Object's constructor is the only constructor you could call, because anonymous classes cannot define custom constructors.
Of course in addition to extending java.lang.Object your anonymous class implements ActionListener - that's why you can pass it to the addActionListener method.
you are constructing a subclass.
Have a quick look at the Java Specification - specifically the Default Constructor Section. You get a constructor because when you instantiate an instance of an interface it would be an Object.
Quote from the spec:
If a class contains no constructor declarations, then a default
constructor with no formal parameters and no throws clause is
implicitly declared.
Anonymous inner class: An inner class with no name.
Now the only detail here we care about is, this new class should subType the interface and for that we provide the necessary method implementations.
The constructor for this class is a default one and performs the job well because there are no instance variables associated.
new java.awt.event.ActionListener(){ }
This statement creates an anonymous class object that implements ActionListener interface.
That is you are invoking anonymous class default constructor not the interface one.
According to java docs
The anonymous class expression consists of the following:
1.The new operator
2.The name of an interface to implement or a class to extend.
3.Parentheses that contain the arguments to a constructor, just like a normal class instance creation expression. Note: In the case of implementing an interface, there is no constructor, so you use an empty pair of parentheses.
How are Anonymous (inner) classes used in Java?
http://www.programmerinterview.com/index.php/java-questions/java-anonymous-class-example/
You are not instantiating an interface. You are asking the compiler to create an anonymous class implementing that interface and immediately create an instance of this class.
The best way to demonstrate this is to go to the "class" directory. You will find files of the form className$1.class, className$2.class, etc. These files correspond to those anonymous classes. If you were instantiating the interface itself, there would be no need for these new class files (and the anonymous classes they contain, of course).
That is how Anonymous Classes are(syntax wise).
According to the docs
The anonymous class expression consists of the following:
The new operator
The name of an interface to implement or a class to extend.
Parentheses that contain the arguments to a constructor, just like a
normal class instance creation expression. Note: In the case of
implementing an interface, there is no constructor, so you use an
empty pair of parentheses.
A body, which is a class declaration body. More specifically, in the
body, method declarations are allowed but statements are not.
Related
I will illustrate my issue with the use of an example:
The addActionListener method accepts an ActionListener Interface as its only argument.
So when invoking that method on an object/component (such as a Button) in order to register a listener to the object, through the use of an anonymous inner class, why is it that we also need to implement the Interface class? Is it because by definition, interfaces cannot be instantiated, unless of course you are creating an object of that Interface type that implements the abstract methods of that Interface?
i.e.
aButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
// do stuff
}
});
That is, through the use of anonymous classes, we can avoid explicitly making the entire class implementing the interface (as declared in the header), but rather we are instantiating an object of the Interface (which by definition of an Interface shouldn't be possible) and implementing the Interface's abstract methods within the anonymous class.
So it is only possible to instantiate an object the Interface due to the fact that at that point in time, a contract needs to be fulfilled to implement the Interface's methods, and in doing so, allows us to make an object from the Interface?
Therefore, is the reason why we can implement the actionPerformed() method of the Interface only possible because of the fact that we had instantiated an object from the Interface (which simultaneously requires us to fulfil the contract of implementing the abstract methods)? So could it be said that we are 'implicitly' implementing an interface by the in-situ instantiation of the Interface (as the addActionListener argument)?
You are not instantiating the interface.
You are defining and instantiating an actual, concrete class that implements the interface. You need to implement every method declared in the interface, just as if you wrote a "normal" class implementing the interface.
The anonymous class construct saves you the trouble of having to name a class that is only going to be used in one very specific place in your code. But if you wanted to you could have decided to do that. Under the covers it is the same thing -- you have defined a class to implement the interface and then instantiated that class.
I am new to java and trying to understand some concepts. Here is a piece of code I don't understand.
public static Comparator<Fruit> FruitNameComparator = new Comparator<Fruit>()
{
public int compare(Fruit fruit1, Fruit fruit2)
{
return fruit1.quantity - fruit2.quantity;
}
};
I know what this is doing, but can't understand why this is allowed. So my questions are:
From the java doc, Comparator[T] is an interface. How about Comparator[Fruit]? I will suppose that it is a class, because it has to override the compare function.
Why can FruitNameComparator be intialized with a non-parameter constuctor and a class definition within the {}? I didn't find such constructor declaration in javadoc of Comparator[T].
Any input will be appreciated.
This code is using a feature of Java called anonymous inner classes. You specify the interface or superclass to implement/extend, along with an anonymous class body. Your anonymous inner class implements Comparator<Fruit>.
It's an anonymous class, which is an in-line concrete implementation of a type (either a super class or an interface).
Implementations are provided for whatever abstract methods are declared by the type.
In the case of super classes, the constructor called can not be specified, so arguments must be provided if there's not a default/no- args constructor.
In the case of interfaces, no parameters may be specified in the constructor because interfaces can not declare constructors.
Btw, I would be inclined to name your field fruitQuantityComparstor, rather than fruitNameComparator, as it compares quantities, not names.
ActionListener is a interface but why can i create instance object?
JButton button = new JButton("Button1");
ActionListener me = new ActionListener(){
public void actionPerformed(ActionEvent ae){
JOptionPane.showMessageDialog(null,ae.getActionCommand());
}
};
button.addActionListener(me);
Or what else? I am not sure. Please help me.
What you're seeing here is called an anonymous class: me will be assigned an instance of an anonymous (un-named) class that implements the ActionListener interface.
Unlike say C#, Java's interfaces cannot prescribe a constructor.
What you are doing in your code is creating an anonymous class that extends java.lang.Object (which does have a default constructor) and implementing the interface.
What you have instantiated is an Anonymous Inner Class. In short, it's an in-line way to both define a class that has no name and instantiate an instance of that class in one statement. You'll only ever be able to refer to anonymous inner classes by the super class they implement or extend. In the case of this question, the super class is the ActionListener interface.
When you compile your code, there will be an extra .class file that exists with a name like this: OuterClass$1.class. That is the class file that represents the anonymous inner class you've defined.
If you want to learn more, check out this section in the JLS http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.9.5
Because you're implementing the interface with your anonymous class
ActionListener itself is an interface, indeed.
However, the construct in your code is an anonymous inner class, meaning that your interface was implemented by that inner class.
Actually, what you are creating is an anonymous subclass of Object.class that implements the interface. So you are "inheriting" the Constructor from Object, not from the interface.
You are not creating an instance of ActionListener. You are creating an anonymous class which implements ActionListener and you are providing that implementation.
ActionListener is in fact an interface which can not be instantiated.
However, by defining public void actionPerformed() locally you are allowing the interface to act like a class.
This is legal:
ActionListener me = new ActionListener(){
public void actionPerformed(...){...};
};
This is not:
ActionListener me = new ActionListener();
1. You can't have constructor in Interface in java.
2. What you saw here is an Anonymous Class, which is declared and initialized simultaneously, and it must extend or implement a class or interface respectively.
In the Eclipse CDT plugin, I found this unusual way of initializing a field of an abstract class.
The field ALL refers is a class of the class itself.
abstract public class IndexFilter {
public static final IndexFilter ALL = new IndexFilter() {};
....
}
What is the role of new IndexFilter() {}; ?
Can you explain this initialization?
IndexFilter() {}; creates an "anonymous subclass" of IndexFilter. Since the braces are empty, the subclass does not override anything in the base class. Since IndexFilter is abstract, it cannot be instantiated directly, hence why a subclass is required.
I think what you refer to as "unusual" is the fact that it's an anonymous inner (or to be more precise, nested) class.
new IndexFilter() {} creates a concrete subclass of IndexFilter and an instance of that subclass in one expression. Obviously this is only possible because IndexFilter hasn't got any abstract methods. If it had, you'd have to provide an implementation for them between the curly braces.
It means that the filter will pass all information. Normally, filter meant to filter some entries. ALL is the special case here. You can also think of NONE as special case which will filter out all information.
Example:
a.select(b, IndexFilter.ALL);
a.select(b, new IndexFilter() {
...
});
Other class that uses such pattern is Integer which has MAX_VALUE and MIN_VALUE.
Looks like it's meant to just be a single easily-accessible instance of IndexFilter which doesn't override anything.
I've noticed that:
class A {
ClassB b = new ClassB() { // anonymous class
/* some expression using this */
}
}
Whenever I use the this keyword inside an anonymous class, the this refers to the enclosing outer class/enum and not to the anonymous class.
Does this mean this can never represent an anonymous class? Just "normal" classes and enums?
Also, can this or super represent an interface?
Your initial assumption is wrong - this always represents the current instance, that is the instance of the current class, even if it's anonymous.
Your statement about using this is incorrect. When you use this inside an anonymous class, it always refers to the anonymous class. It never refers to the enclosing outer class unless you use OuterClassName.this.
this or super can never represent an interface, since an interface cannot have defined methods.
In Java this is always the current class even if it is an anonymous class. No, this or super cannot represent an interface.
Your anonymous class always extends another class. Even if you explicitly implement an interface, you are extending java.lang.Object and you can only call methods of java.lang.Object via super calls.
Runnable r = new Runnable() {
public void run() {
super.run(); // Error: run() is not a method of java.lang.Object
super.toString(); // OK: toString() is inherited from java.lang.Object
}
};
Use A.this from the inner class.
And it cannot represent an interface, because you cannot define anynomous non-static classes within interfaces, because there wil never be an instance of the interface.
EDIT: Clarified by adding info from the comment.