How Are Anonymous Inner Classes Used in Java

How are Anonymous inner classes used in Java?

By an "anonymous class", I take it you mean anonymous inner class.

An anonymous inner class can come useful when making an instance of an object with certain "extras" such as overriding methods, without having to actually subclass a class.

I tend to use it as a shortcut for attaching an event listener:

button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// do something
}
});

Using this method makes coding a little bit quicker, as I don't need to make an extra class that implements ActionListener -- I can just instantiate an anonymous inner class without actually making a separate class.

I only use this technique for "quick and dirty" tasks where making an entire class feels unnecessary. Having multiple anonymous inner classes that do exactly the same thing should be refactored to an actual class, be it an inner class or a separate class.

Why use Anonymous Inner classes, and what are the alternatives?

One alternative pattern is to make the container class itself a listener.

public class MyClass implements View.OnClickListener {
@Override
public void onClick(View v) {
// Do something when button is clicked
}

public void initOrSomething() {
button.setOnClickListener(this);
}
}

However you may run into trouble if you have more than one button that needs to behave differently.

Another way is to have different listener classes for each button

public class Button1Listener implements View.OnClickListener {
@Override
public void onClick(View v) {
// Do something when button1 is clicked
}
}

public class Button2Listener implements View.OnClickListener {
@Override
public void onClick(View v) {
// Do something when button2 is clicked
}
}


button1.setOnClickListener(new Button1Listener());
button2.setOnClickListener(new Button2Listener());

Anonymous inner classes are just a more compact representation of the second pattern.

EDIT: Variations of both patterns are possible, where contents of the View object are examined to determine which button was clicked or constructor arguments are passed to the listener class to change listener behavior etc.

Confused about anonymous classes vs anonymous inner class

First off - square can access fields in Rectangle. You need to mark them protected not private

public class Rectangle {
protected double length;
protected double width;
protected double perimeter;

public void calculatePerimeter() {
perimeter = (2*length) +(2*width);
}

public static void main(String[] args) {
Rectangle square = new Rectangle() {
public void calculatePerimeter() {
perimeter = 4*length;
}
};
}

}

Here are some good descriptions of Inner Classes, Anonymous and local

  • http://docs.oracle.com/javase/tutorial/java/javaOO/innerclasses.html.

There are two additional types of inner classes. You can declare an inner class within the body of a method. These classes are known as local classes. You can also declare an inner class within the body of a method without naming the class. These classes are known as anonymous classes.

  • http://docs.oracle.com/javase/tutorial/java/javaOO/localclasses.html

Local classes are classes that are defined in a block, which is a group of zero or more statements between balanced braces. You typically find local classes defined in the body of a method.

  • http://docs.oracle.com/javase/tutorial/java/javaOO/anonymousclasses.html
  • http://c2.com/cgi/wiki?AnonymousInnerClass

Anonymous Classes enable you to make your code more concise. They enable you to declare and instantiate a class at the same time. They are like local classes except that they do not have a name. Use them if you need to use a local class only once.

I think the relevance of Anonymous classes comes when you are designing an API. You could create concrete classes to implement every bit of logic for every interface/abstract class but that would create tons of dependencies and you would still be missing some logic. A great example of anonymous classes is when using predicates for filtering. Like in Google Guava

Lets say I have a List<Integer> and I want to filter the numbers remove the 1s and return a new list

public static List<Integer> filter(List<Integer> input) {
List<Integer> rtn = new ArrayList<Integer>();
for( Integer i : input) {
if(i != 1) rtn.push(i);
}
return rtn;
}

Now lets say I want to filter out 1 and 2

public static List<Integer> filter(List<Integer> input) {
List<Integer> rtn = new ArrayList<Integer>();
for( Integer i : input) {
if(i != 1 && i != 2) rtn.push(i);
}
return rtn;
}

Now lets say 3 and 5s ... this logic is exactly the same except for the predicate check. So we will create an interface

interface FilterNumber {
public boolean test(Integer i);
}

class Filter1s implements FilterNumber {
public Filter1s(){};
public boolean test(Integer i) { return i != 1; }
}


public static List<Integer> filter(List<Integer> input, FilterNumber filterNumber) {
List<Integer> rtn = new ArrayList<Integer>();
for( Integer i : input) {
if(filterNumber.test(i)) rtn.push(i);
}
return rtn;
}

filter(list, new Filter1s());

As you can see with combinations this becomes tedious too. It would be easier to just allow the user of the api to define the logic they want to preform and if it is only needed once just use an anonymous class

filter(list, new FilterNumber() {
@Override
public boolean test(Integer i) {
return i != 1 && i != 3 && i != 7;
}
});

And extending to Lambdas, wouldn't it be even easier to take out all the bloat around i != 1

list.stream().filter( i -> i != 1 )

Anonymous Inner Classes Inside Methods

Essentially the code is rewritten by the complier as (note I didn't try to compile it..., might have errors):

class Main$1<T>
extends ArrayList<T>
{
private final List<T> list;

Main$1(final List<T> a)
{
list = a;
}

@Override
public boolean add(T element)
{
super.add(element);
return list.add(element);
}
}

and

class Main{
public static <T> List<T> modifiedList(final List<T> list)
{
return new Main$1<T>(list);
}

public static void main(String[] args)
{
List<String> originalList=new ArrayList<String>();
List<String> duplicateList=modifiedList(originalList);
originalList.add("1");
originalList.add("2");
originalList.add("3");
System.out.println(originalList+" "+duplicateList);
duplicateList.add("4");
duplicateList.add("5");
duplicateList.add("6");
System.out.println(originalList+" "+duplicateList);
}

What are the advantages of Anonymous Inner Class (over non-anonymous inner class)?

The anonymous inner class has advantage over the inner class (as in the question example code) in that it closes over the local variables of the method (although only final locals are usable).

Generally an inner class can be easily converted into a method with anonymous inner class, which helps reduce verbosity. If you've got an inner class that is so large that you want to make it non-local, you might want to think about battling with your IDE to put it in a new file as an outer class.

(The is also local classes, which are normal named inner classes defined within a method and that close over locals.)

Anonymous inner class - getClass()

You are creating instances of the class on the second sample:

AnonymousClasses jonny = new AnonymousClasses(new GreetingModule(){
@Override
public void sayHello() {
System.out.println("Hey");
}
});

To create a anonymous subclass of it would like:

AnonymousClasses jonny = new AnonymousClasses(new GreetingModule(){
@Override
public void sayHello() {
System.out.println("Hey");
}
}) {
// Overriding anything here is optional
};

Aren't Anonymous Inner Classes actually subclasses?

To answer your question's title, yes, they are. Anonymous inner classes are actually subclasses.

"Since it was declared with type A, the anonymous class, [Obj], must be a subclass of A."

Good job. :)

Anyways, to answer why the "inner" is there: If you declare an anonymous class inside another class (and the anonymous class isn't declared statically, more on that below) then it would be able to access its surrounding class just like an inner class would. For example:

public class Outer {
private final int someRandomValue = 4;

public final Object anonymousInnerInstance = new Object() {
@Override
public String toString() {
// Notice how this class has access to a field declared inside a different
// class. More specifically, this anonymous class can access someRandomValue,
// even though someRandomValue belongs to the class, Outer.
return "Anonymous Inner Class: " + someRandomValue;
}
};

public class RegularInner {
@Override
public String toString() {
// This regular inner class is inside Outer, (just like the anonymous class),
// and can access any of Outer's fields (amongst Outer's other things).
return "Regular Inner Class: " + someRandomValue;
}
}

public final RegularInner regularInnerInstance = new RegularInner();

public static void main(String[] args) {
Outer outerInstance = new Outer();
System.out.println(outerInstance.anonymousInnerInstance);
System.out.println(outerInstance.regularInnerInstance);

// By the way, you can make new RegularInner instances off of our Outer
// instance:
RegularInner newInnerInstance = outerInstance.new RegularInner();
// When you write "outerInstance.new SomeClass()" you're saying:
// "I'd like to initialize my 'SomeClass' object with 'outerInstance',
// as its container." This effectively means that any variables that
// belong to Outer that your SomeClass needs to access, it will access
// from the Outer instance you gave it.
}
}

So, anonymousInnerInstance's underlying class, and the class RegularInner, both have access to Outer's fields, and other instance-specific content belonging to Outer. That's why an anonymous class may sometimes be called an "inner" class.

Any instance of an inner class needs to be created with an instance of an outer class to back it up, or it won't know which object, (not class), it belongs to.


Static Trash

If an anonymous class is declared as static, it won't have access to its surrounding class's content and wouldn't be an "inner" class (instead, it would be an anonymous "nested" class).

public class Outer {
private final int someRandomValue = 4;

public static final Object anonymousStaticInstance = new Object() {
@Override
public String toString() {
// someRandomValue belongs to an INSTANCE of Outer. (So each Outer object you
// have has its own someRandomValue). Since this anonymous class
// is now static, it is no longer tied to an instance of Outer. It doesn't have
// an Outer object that it can read "someRandomValue" from. The same goes for
// RegularStatic, below.
return "Anonymous Inner Class: " + someRandomValue;
}
};

public static class RegularStatic {
@Override
public String toString() {
return "Regular Inner Class: " + someRandomValue;
}
}

public final RegularStatic regularInnerInstance = new RegularStatic();

public static void main(String[] args) {
Outer outerInstance = new Outer();
System.out.println(outerInstance.anonymousStaticInstance);// Java warns you here and
// tells you to access anonymousStaticInstance statically. This is because
// anonymousStaticInstance no longer belongs to any given instance of Outer.
// There is only one anonymousStaticInstance, that "belongs" to the class Outer,
// rather than multiple anonymousInnerInstances which each belong to an instance
// of Outer.
System.out.println(outerInstance.regularInnerInstance);
}
}

Remember that anonymous classes can be "inner" OR "nested". So when talking about them in general, just say "anonymous class". (Anonymous inner classes are a type of anonymous class). Also, do make sure to read the comments as they give most of the explanation.

Any questions? :)

Anonymous inner class using an interface in Java

1) Why are we able to create an anonymous inner class directly from an
interface rather than having to create one through a class that
implements the interface?

2) Why am I unable to create an anonymous inner class that implements
ActionListener instead of directly from it as I show in my second code
snippet?

When you create a class using implements XXXX, you are defining a class(inner or non-inner), and you will have to give it a name, sure we can do that and this is what we often do . While anonymous inner class dose not have a name, and it is more like an expression.


I copy this from http://docs.oracle.com/javase/tutorial/java/javaOO/anonymousclasses.html

And I think this will help you to understand what anonymous class is.

An anonymous class is an expression. They are like local classes except that they do not have a name

. The syntax of an anonymous class expression is like the invocation of a constructor, except that there is a class definition contained in a block of code.

Consider the instantiation of the frenchGreeting object:

    HelloWorld frenchGreeting = new HelloWorld() {
String name = "tout le monde";
public void greet() {
greetSomeone("tout le monde");
}
public void greetSomeone(String someone) {
name = someone;
System.out.println("Salut " + name);
}
};

The anonymous class expression consists of the following:

  • The new operator

  • The name of an interface to implement or a class to extend. In this example, the anonymous class is implementing the interface HelloWorld.

  • Parentheses that contain the arguments to a constructor, just like a normal class instance creation expression. Note: When you implement an interface, there is no constructor, so you use an empty pair of parentheses, as in this example.

  • A body, which is a class declaration body. More specifically, in the body, method declarations are allowed but statements are not.

Because an anonymous class definition is an expression, it must be part of a statement. In this example, the anonymous class expression is part of the statement that instantiates the frenchGreeting object. (This explains why there is a semicolon after the closing brace.)

How huge would anonymous inner class impact performance if it is heavily used?

There's basically two issues here, neither of them really have to do with the anonymous aspect. Anonymous classes aren't really any different than regular inner classes except that they don't have a name. An anonymous inner class gets compiled to a regular inner class, which in turn is still not really any different from a static nested class.

Issue 1 is that since they are inner, they keep a reference to the enclosing class:

class Outer {
interface Inner {}

Inner inner = new Inner() {
{
System.out.println(Outer.this);
}
};
}

This is not so much an issue and most of the time it's desired because you are doing something functional and want to use the outer instance's members inside the inner class. But it could create problems since as long as the inner class is alive, the outer class can't be garbage collected.

Issue 2 is that indeed they are an object so indeed your methodB is creating a new one each time it's called.

The obvious solution is just to create it once:

class MyProcess {

final Completion myCompletion = new Completion() {
@Override
public void success() {}
@Override
public void fail(String err) {}
}

void methodA(Completion c) {}

void methodB() {
methodA(myCompletion);
}
}

It seems like what you like is the syntax though and there's not really a solution to keep the syntax and not create an object at the same time.

My personal opinion: if you aren't calling this method a lot, I agree the syntax can be nice and clear. If you are calling it a lot, switch to a single object because you are crowding memory space. If it gets called 1000 times, that's 1000 objects. Object size differs by platform, but it's typically a minimum 8 or 16 bytes + a pointer to the outer instance. That's not a huge impact but it could, for example, prompt garbage collection to run which can cause subtle stalling.

By the way, I was thinking about this again and thought of the following idea:

Completion myLazyCompletion;

void methodB() {
methodA(myLazyCompletion != null ? myLazyCompletion :
(myLazyCompletion = new Completion() {

// overrides

})
);
}

I would say don't do that, but I thought it was interesting. : )



Related Topics



Leave a reply



Submit