Anonymous Class Instance - Is It a Bad Idea

Anonymous class instance — is it a bad idea?

Immediately instantiated anonymous class — is it a bad idea?

Yes, a very bad one. Just as bad as new function() { … } was in ES5.

This writing style leads to the creation of a new constructor function and prototype object every time the expression is evaluated. If you create multiple objects with this approach, they will get none of the benefits of classes/prototypes.

If you intended this pattern to create a singleton object, you failed as well. The constructor is still created, and it is even accessible - a second instance can be easily created using new entity.constructor, defeating the whole purpose.

So don't use it ever. A simple object literal is much easier to write, read and instantiate:

var entity = {
name: 'Foo',
getName() { return this.name; }
};
console.log(entity.name); // Foo

Don't be fooled by other languages where the new class pattern is common, it works very different there than in JavaScript.

Is usage of anonymous classes in Java considered bad style or good?

I tend to use anonymous inner classes in situations where I don't need to have a full-blown class just to perform some task. For example, if I want to implement an ActionListener or Runnable, but I don't think having an inner class would be necessary. For example, for starting a simple Thread, using an anonymous inner class might be more readable:

public void someMethod()
{
new Thread(new Runnable() {
public void run()
{
// do stuff
}
}).start();
}

In certain cases, such as the example above, it can increase readability, especially for one-time tasks, as the code that is to be executed is all written in one spot. Using an inner class would "delocalize" the code:

public void someMethod()
{
new Thread(new MyRunnable()).start();
}

// ... several methods down ... //

class MyRunnable implements Runnable
{
public void run()
{
// do stuff
}
}

That said, however, if there is going to be cases where the same thing is going to be repeated, it should indeed be a separate class, be it a regular class or an inner class.

I tend to use anonymous inner classes in programs where I am just trying things out rather than have it as a central feature of an actual application.

When to use anonymous classes?

Are there any cases when it is unavoidable to use anonymous classes

No, you can always just use a private inner class instead of an Anonymous class.


using anonymous classes makes the code hard to read and can cause a lot of headache

This very much depends on how you use anonymous classes. Consider the following example:

new Thread(new Runnable() {
@Override
public void run() {
// do something
}
}).start();

In this example you create a Runnable which is run by a thread. If you wouldn't use an anonymous class you'd have to write it as follows:

private class SomeClass implements Runnable {
@Override
public void run() {
// TODO Auto-generated method stub

}
}

and use it as:

new Thread(new SomeClass()).start();

With the first possibility you can directly see what that thread is doing, in the second possibility you'll first have to find the class that is used here.


Another advantage of anonymous classes. You can do the following:

// define some constant which can be used in the anonymous class:
final String someStr = "whatever";

new Thread(new Runnable() {
@Override
public void run() {
// use the String someStr directly
System.out.println(someStr);
}
}).start();

You can use the constant which is declared in the code where the anonymous class is defined. If you'd use a private inner class you'd have to give these constants to the constructor of the class in order to use them!

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. : )

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 )

Java (anonymous or not) inner classes: is it good to use them?

In my view, 90% of inner classes in Java code are either entities that are associated with a single class and were thus "shoved in" as inner classes, or anonymous inner classes that exist because Java does not support Lambdas.

I personally don't like seeing complex inner classes. They add complexity to the source file, they make it bigger, they're ugly to deal with in terms of debugging and profiling, etc. I like separating my project into many packages, in which case I can make most entities top-level classes that are restricted to the package.

That leaves me with necessary inner classes - such as action listeners, fake "functional" programming, etc. These are often anonymous and while I'm not a fan (would have preferred a Lambda in many cases), I live with them but don't like them.

I haven't done any C# in years, but I'm wondering if the prevalence of inner classes or whatever the C# equivalent is dropped when they introduced Lambdas.

Java Classes: Anonymous vs Nested vs Private

Can someone explain the difference between anonymous classes, nested classes and private classes in Java?

  • Anonymous classes are for instance the Runnable in

    new Thread(new Runnable() {
    public void run() {
    ...
    }
    }.start();
  • Nested classes look like

    class SomeClass {

    ...

    class NestedClass {
    ....
    }
    }
  • Private classes (which you refer to as "the ones you write at the bottom of your file completely outside the declaration of your public class") are actually package scoped classes. You can't have the private modifier in front of a class, unless it is nested!

I'd like to know the runtime costs associated with each and the compiler approach to each, so I can get a grip on which is best to use for e.g. performance (potential for compiler optimisations), memory usage, and general acceptability with other Java coders.

I doubt that there is any performance difference between these approaches. Why? Because each approach ends up as being compiled into a separate more or less "regular" class. ("More or less" due to the fact that an accesss-method is generated in some cases, but it's side effect free and most likely inlined by the JIT anyway.)

This code:

public class TestOuter {

int fieldOuter;
public void methodOuter() {
}

class TestInner {
int fieldInner;
public void methodInner() {
}
}
}

class TestPackage {

int fieldPackage;
public void methodPackage() {
}

}

Gets compiled into:

$ javap -c TestOuter$TestInner
Compiled from "TestOuter.java"
public class TestOuter extends java.lang.Object{
int fieldOuter;

public TestOuter();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()V
4: return

public void methodOuter();
Code:
0: return

}

$ javap -c TestOuter
Compiled from "TestOuter.java"
public class TestOuter extends java.lang.Object{
int fieldOuter;

public TestOuter();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()V
4: return

public void methodOuter();
Code:
0: return

}

$ javap -c TestPackage
Compiled from "TestOuter.java"
class TestPackage extends java.lang.Object{
int fieldPackage;

TestPackage();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()V
4: return

public void methodPackage();
Code:
0: return

}


Related Topics



Leave a reply



Submit