What is the use of anonymous classes in Java? Can we say that usage of anonymous class is one of the advantages of Java?
One of the major usage of anonymous classes in class-finalization which called finalizer guardian. In Java world using the finalize methods should be avoided until you really need them. You have to remember, when you override the finalize method for sub-classes, you should always invoke super.finalize()
as well, because the finalize method of super class won't invoke automatically and you can have trouble with memory leaks.
so considering the fact mentioned above, you can just use the anonymous classes like:
public class HeavyClass{
private final Object finalizerGuardian = new Object() {
@Override
protected void finalize() throws Throwable{
//Finalize outer HeavyClass object
}
};
}
Using this technique you relieved yourself and your other developers to call super.finalize()
on each sub-class of the HeavyClass
which needs finalize method.
One more advantage:
As you know that Java doesn't support multiple inheritance, so if you use "Thread" kinda class as anonymous class then the class still has one space left for any other class to extend.
Yes, anonymous inner classes is definitely one of the advantages of Java.
With an anonymous inner class you have access to final and member variables of the surrounding class, and that comes in handy in listeners etc.
But a major advantage is that the inner class code, which is (at least should be) tightly coupled to the surrounding class/method/block, has a specific context (the surrounding class, method, and block).
GuideLines for Anonymous Class.
Anonymous class is declared and initialized simultaneously.
Anonymous class must extend or implement to one and only one class or interface resp.
As anonymouse class has no name, it can be used only once.
eg:
button.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent arg0) {
// TODO Auto-generated method stub
}
});
Anonymous inner classes are effectively closures, so they can be used to emulate lambda expressions or "delegates". For example, take this interface:
public interface F<A, B> {
B f(A a);
}
You can use this anonymously to create a first-class function in Java. Let's say you have the following method that returns the first number larger than i in the given list, or i if no number is larger:
public static int larger(final List<Integer> ns, final int i) {
for (Integer n : ns)
if (n > i)
return n;
return i;
}
And then you have another method that returns the first number smaller than i in the given list, or i if no number is smaller:
public static int smaller(final List<Integer> ns, final int i) {
for (Integer n : ns)
if (n < i)
return n;
return i;
}
These methods are almost identical. Using the first-class function type F, we can rewrite these into one method as follows:
public static <T> T firstMatch(final List<T> ts, final F<T, Boolean> f, T z) {
for (T t : ts)
if (f.f(t))
return t;
return z;
}
You can use an anonymous class to use the firstMatch method:
F<Integer, Boolean> greaterThanTen = new F<Integer, Boolean> {
Boolean f(final Integer n) {
return n > 10;
}
};
int moreThanMyFingersCanCount = firstMatch(xs, greaterThanTen, x);
This is a really contrived example, but its easy to see that being able to pass functions around as if they were values is a pretty useful feature. See "Can Your Programming Language Do This" by Joel himself.
A nice library for programming Java in this style: Functional Java.
Seems nobody mentioned here but you can also use anonymous class to hold generic type argument (which normally lost due to type erasure):
public abstract class TypeHolder<T> {
private final Type type;
public TypeReference() {
// you may do do additional sanity checks here
final Type superClass = getClass().getGenericSuperclass();
this.type = ((ParameterizedType) superClass).getActualTypeArguments()[0];
}
public final Type getType() {
return this.type;
}
}
If you'll instantiate this class in anonymous way
TypeHolder<List<String>, Map<Ineger, Long>> holder =
new TypeHolder<List<String>, Map<Ineger, Long>>() {};
then such holder
instance will contain non-erasured definition of passed type.
This is very handy for building validators/deserializators. Also you can instantiate generic type with reflection (so if you ever wanted to do new T()
in parametrized type - you are welcome!).