Are there performance issues with creating many anonymous classes? [duplicate] - java

Is there any difference in efficiency (e.g. execution time, code size, etc.) between these two ways of doing things?
Below are contrived examples that create objects and do nothing, but my actual scenarios may be creating new Threads, Listeners, etc. Assume the following pieces of code happen in a loop so that it might make a difference.
Using anonymous objects:
void doSomething() {
for (/* Assume some loop */) {
final Object obj1, obj2; // some free variables
IWorker anonymousWorker = new IWorker() {
doWork() {
// do things that refer to obj1 and obj2
}
};
}
}
Defining a class first:
void doSomething() {
for (/* Assume some loop */) {
Object obj1, obj2;
IWorker worker = new Worker(obj1, obj2);
}
}
static class Worker implements IWorker {
private Object obj1, obj2;
public CustomObject(Object obj1, Object obj2) {/* blah blah */}
#Override
public void doWork() {}
};

The only practical difference between the anonymous classes and the top-level classes is that the anonymous classes will hold an implicit reference to the outer class.
This won't manifest itself in performance, but will impact you if you ever serialise these classes.

There should be little if any performance difference. If there is a difference it will be at a level where it is not worth worrying about.
IMO, you should focus on writing code that is readable and maintainable, and ignore "micro" performance issues until you have clear evidence that they are significant ... based on profiling the application.
(For the record, when an anonymous inner class refers to a final in an enclosing scope, this is implemented at the bytecode level by means of hidden constructor arguments and hidden instance attributes. The bytecodes will be almost the same as the bytecodes that you get from your other implementation.)

It's important to realize that anonymous classes are still classes that were known and fully-compiled at compile time. The fact that, say, you're defining an anonymous class body, perhaps with many methods and fields etc within a loop, doesn't mean that the runtime has to compile that type on every iteration.
Thus, any difference in performance between the two approaches are negligible. The important factors to consider are things like readability, reusability, testability, etc.

I actually HAVE noticed a significance performance hit when instantiating many instances of an anonymous class.
Thinking if might be due to the local class being static I removed that and it made no difference.
In my case, I was doing something 1000 choose 3 times which is 499,500. The version with the local class (regardless of static or not) took 26 seconds and the version with the anonymous functionally identical class took 2 minutes 20 seconds.

Regarding performance you should consider if an inner class should be created or not at all.
An example for bad practice is something like:
public List<String> someMethod() {
return new ArrayList<String>() {{
add("Item one");
add("Item two");
}};
}
While this syntactical convenience looks smart at a first glance, this (often unnoticed) creates an anonymous inner class whose object keeps a reference to the outer instance.
As this object is also given to the outside as result value of someMethod, you cannot be sure what your caller does with this list.
If he puts the resulting ArrayList instance into some static variable, your current Object will be kept forever too!

Speculating about code performance is an excellent way of wasting your time. Nothing compares to actually benchmarking the code. If you're worried about performance, measure the code. If you suspect that your code is sub-optimal, profile the code to figure out where the time is spent, then try to improve those parts. At this time it may be appropriate to actually study the byte code to see if that may give you a hint which implementation is more efficient.
When you've done that, measure the code again to make sure that you didn't make things worse, for example by making the code uglier and more difficult to maintain.

Related

Drawbacks of explicitly implementing not used interface

I came up with this question writing specific code, but I'll try to keep the question as generic as possible.
Other similar question refer to C# which seems to have some language specific handling for this and below code is Java, but again let's try to keep it generic.
Let's say I have class A which implements interface I.
This is useful to me cause I can implement methods that use A only as a I type and abstract the implementation.
Let's now say, I have class B which implements all methods in interface I, but it's never referred to as only I.
Let's now say, I have class B which implements methods that have the same name/signature as the ones in interface I, but it doesn't implements the interface.
Should I always explicitly implement I?
Even if I don't use it (though I might in the future) for type abstraction?
A more meaningful, even if probably not realistic, example would be:
interface Printable {
String print()
class A implements Printable {
//code...
String print(){return "A";}
//code...
}
class B {
//code...
String print(){return "B";}
void otherMethod(){/*code*/}
//code...
}
class Test {
Printable a = new A();
System.out.println(a.print());
B b = new B();
b.otherMethod();
System.out.println(b.print());
}
Are there any drawbacks on explicitly implementing, or not, the interface Printable?
The only one I can think of is scalability for the second case.
In the sense that if one day I'll want to explicitly use it as Printable, I'll be able to do so without any more effort.
But is there anything else (patterns, optimization, good programming, style, ..) I should take into consideration?
In some cases the type hierarchy will affect the method call cost due to not playing well with JIT method inlining. An example of that can be found in Guava ImmutableList (and others) offer awful performance in some cases due to size-optmized specializations #1268 bug:
Many of the guava Immutable collections have a cute trick where they have specializations for zero (EmptyImmutableList) and one (SingletonImmutableList) element collections. These specializations take the form of subclasses of ImmutableList, to go along with the "Regular" implementation and a few other specializations like ReverseImmutable, SubList, etc.
Unfortunately, the result is that when these subclasses mix at some call site, the call is megamorphic, and performance is awful compared to classes without these specializations (worse by a factor of 20 or more).
I don't think there is a simple correct answer for this question.
However, if you do not implement the method, you should do this:
public void unusedBlahMethod() {
throw new UnsupportedOperationException("operation blah not supported");
}
The advantages of omitting the unused method are:
You save yourself time and money (at least in the short term).
Since you don't need the method, it might not be clear to you how best to implement it anyway.
The disadvantages of omitting the method are:
If you need the method in the future, it will take longer to add it as you may have to refamiliarize yourself with the code, check-out, re-test, etc.
Throwing an UnsupportedOperationException may cause bugs in the future (though good test coverage should prevent that).
If you're writing disposable code, you don't need to write interfaces, but one day you might notice, that you should've taken your time and write an interface.
The main advantage and purpose of interfaces is the flexibility of using different implementations. I can put something, that offers the same functionality inside a method, I can create a fake of it for test purposes and I can create a decorator that behaves like the original object, but can log the stuff.
Example:
public interface A {
void someMethod();
}
public class AImplementation {
#Override
public void someMethod() {
// implementation
}
}
public class ADecorator {
private final A a;
public ADecorator(A a) {
this.a = a;
}
#Override
public void someMethod() {
System.out.println("Before method call");
a.someMethod();
System.out.println("After method call");
}
}
Nice side effect: ADecorator works with every implementation of A.
The cost for this flexibility isn't that high and if your code will live a little bit longer, you should take it.

Efficiency of accessing local variable vs field?

I read that you should avoid referencing a field too often in a method and instead just do it once, assigning it to a local variable, e.g.:
public static void doSomething() {
final Map<String, Integer> myMap = this.theMap;
//do some processing with myMap
}
The reason being efficiency, it just takes longer to access the field every time. Is that something you should worry about?
This is absolutely wrong.
It makes no difference at all how the variable is accessed (locally or using the class' member). In the end both fields will just contain a reference to the very same location in the memory without any impact to performance. Even when using a getter for your class' field it will make no difference as the JIT compiler will inline the method call once it noticed that this might improve performance.
Optimisationwise: it does nothing really. Any benefit if any would also be provided by an optimizer.
Only benefit is for you, the coder, by being able to name it differently so you know it's purpose in the method better.
public function test() {
Produce harvestedFruits = this.produce;
for(Produce fruit : harvestedFruits ) {
if(fruit.isRotten()) {
harvestFruits.remove(fruit);
}
}
}
And even then, I'd advice using getter and setter methods, so extended functions can do their own thing and testing becomes easier, and with documentation you provide nice highlights when hovering over the method in an relatively advanced IDE
Produce fruit = this.getProduce();

Why does having static members make a language less object-orientated?

I'm learning Scala at the moment and I came across this statement in Odersky's Programming Scala 2nd edition:
one way in which Scala is more object-orientated than Java is that classes in Scala cannot have static members.
I'm not sufficiently experienced in either Java or Scala to understand that comparison. Why does having static members make a language less OO?
Odersky's statement is valid and significant, but some people don't understand what he meant.
Let's say that in Java you have a class Foo with method f:
class Foo {
int f() { /* does something great */ }
}
You can write a method that takes a Foo and invokes f on it:
void g(Foo foo) { foo.f(); }
Perhaps there is a class SubFoo that extends Foo; g works on that too. There can be a whole set of classes, related by inheritance or by an interface, which share the fact that they can be used with g.
Now let's make that f method static:
class Foo {
static int f() { /* does something great */ }
}
Can we use this new Foo with g, perhaps like so?
g(Foo); // No, this is nonsense.
Darn. OK, let's change the signature of g so that we can pass Foo to it and have it invoke f.
Ooops -- we can't. We can't pass around a reference to Foo because Foo is not an instance of some class. Some people commenting here are confused by the fact that there is a Class object corresponding to Foo, but as Sotirios tried to explain, that Class object does not have an f method and Foo is not an instance of that class. Foo is not an instance of anything; it is not an object at all. The Class object for Foo is an instance of class Class that has information about Foo (think of it as Foo's internal Wikipedia page), and is completely irrelevant to the discussion. The Wikipedia page for "tiger" is not a tiger.
In Java, "primitives" like 3 and 'x' are not objects. They are objects in Scala. For performance your program will use JVM primitives for 3 and 'x' wherever possible during execution, but at the level you code in they really are objects. The fact that they are not objects in Java has rather unfortunate consequences for anyone trying to write code that handles all data types -- you have to have special logic and additional methods to cover primitives. If you've ever seen or written that kind of code, you know that it's awful. Odersky's statement is not "purism"; far from it.
In Scala there is no piece of runtime data that is not an object, and there is no thing you can invoke methods on that is not an object. In Java neither of these statements in true; Java is a partially object-oriented language. In Java there are things which are not objects and there are methods which aren't on objects.
Newcomers to Scala often think of object Foo as some weird replacement for Java statics, but that's something you need to get past quickly. Instead think of Java's static methods as a non-OO wart and Scala's object Foo { ... } as something along these lines:
class SomeHiddenClass { ... }
val Foo = new SomeHiddenClass // the only instance of it
Here Foo is a value, not a type, and it really is an object. It can be passed to a method. It can extend some other class. For example:
abstract class AbFoo { def f:Int }
object Foo extends AbFoo { def f = 2 }
Now, finally, you can say
g(Foo)
It is true that a "companion object" for a class is a good place to put non-instance methods and data for the class. But that companion object is an object, so the usual rules and capabilities apply.
The fact that in Java you put such methods on non-objects -- limiting how they can be used -- is a liability, not a feature. It is certainly not OO.
I am not sure I completely buy that argument, but here is one possible reasoning.
To an object-oriented purist, everything should be an object, and all state should be encapsulated by objects. Any static member of a class is by definition state which exists outside of an object, because you can use it and manipulate it without instantiating an object. Thus, the lack of static class members makes for a more pure object-oriented language.
Well, with static members like methods you don't have any objects to create and nevertheless you can call such static methods. You only need the static classname in order to set the namespace for these methods, for example:
long timeNow = System.currentTimeMillis(); // no object creation
This rather gives a feeling like in procedural languages.
static members belongs to the Class not to the object while the main concept of oop lies among the relation between the individual objects of dirrefer Class.
A static method in Java is one that operates on the class itself, and doesn't need an Object to be created first. For example, this line:
int c = Integer.parseInt("5");
Integer.parseInt() is static because I didn't have to go Integer i = new Integer(); before using it; this isn't operating on any particular object that I've created, since it's always going to be the same, and is more like a typical procedural function call instead of an object-oriented method. It's more object-oriented if I have to create an object for every call and we encapsulate everything that way instead of allowing static to use methods as faux-procedural-functions.
There are several competing definitions of what exactly object-orientation means. However, there is one thing they all can agree on: dynamic dispatch is a fundamental part of the definition of OO.
Static methods are static (duh), not dynamic, ergo they are by definition not object-oriented.
And logically, a language that has a feature which isn't object-oriented is in some sense "less OO" than a language which doesn't have said feature.

What's the harm in using Anonymous class?

The question arose while reading a answer to this question - How do I join two lists in java. This answer gave the solution
List<String> newList = new ArrayList<String>() { { addAll(listOne); addAll(listTwo); } };
Reading the comments, users said it was evil and ugly and should not be used in production.
I would like to know what's the harm in using this? Why is it ugly, evil or bad to use in production?
Except for the already mentioned issues regarding good programming style and inheritance misuse, there is one more subtle problem - inner classes and (non-static) anonymous class instances act as closures. This means that they keep an implicit reference to the enclosing class instance. This can result in preventing of garbage collection and in the end, a memory leak.
Given an example piece of source code:
public interface Inner {
void innerAction();
}
public class Outer {
public void methodInOuter() {}
private Inner inner = new Inner() {
public void innerAction() {
// calling a method outside of scope of this anonymous class
methodInOuter();
}
}
}
What happens at compilation time, is that the compiler creates a class file for the new anonymous subclass of Inner which gets a so-called synthetic field with the reference to the instance of the Outer class. The generated bytecode will be roughly equivalent to something like this:
public class Outer$1 implements Inner {
private final Outer outer; // synthetic reference to enclosing instance
public Outer$1(Outer outer) {
this.outer = outer;
}
public void innerAction() {
// the method outside of scope is called through the reference to Outer
outer.methodInOuter();
}
}
Such capture of reference to the enclosing instance happens even for anonymous classes that never actually access any of methods or fields of the enclosing class, such as the double-brace initialized (DBI) list in your question.
This results in the fact that the DBI list keeps a reference to the enclosing instance as long as it exists, preventing the enclosing instance from being garbage collected. Suppose the DBI list happens to live for a long time in the application, for example as a part of the model in MVC pattern, and the captured enclosing class is for example a JFrame, which is quite a large class with lots of fields. If you created a couple of DBI lists, you would get a memory leak very quickly.
One possible solution would be using DBI only in static methods, because there is no such enclosing instance available in their scope.
On the other hand, I would still argue that using DBI is still not necessary in most cases. As for the list joining, I would create a simple reusable method, which is not only safer, but also more concise and clear.
public static <T> List<T> join(List<? extends T> first, List<? extends T> second) {
List<T> joined = new ArrayList<>();
joined.addAll(first);
joined.addAll(second);
return joined;
}
And then the client code becomes simply:
List<String> newList = join(listOne, listTwo);
Further reading:
https://stackoverflow.com/a/924536/1064809
The "ugly" and "do not use in production" comments refer to this specific use of anonymous classes, not to anonymous classes in general.
This specific use assigns newList an anonymous subclass of ArrayList<String>, an entirely new class created with a single purpose in mind - namely, initializing a list with the content of two specific lists. This is not very readable (even an experienced reader would spend a few seconds figuring it out), but more importantly, it can be achieved without subclassing in the same number of operations.
Essentially, the solution pays for a small convenience with creating a new subclass, which may result in problems down the road, for example, in situations when you try to persist this collection using an automated framework that expects collections to have specific types.
This particular use of anonymous classes has several problems:
it's a little-known idiom. Developers that don't know it (or know it an don't use it a lot) will be slowed down when reading and/or modifying code that uses it.
it's actually misusing a language feature: you're not trying to define a new kind of ArrayList, you just want some array list with some existing values in it
it creates a new class that takes up resources: disk space to hold the class definition, time to parse/verify/... it, permgen to hold the class definition, ...
even if the "real code" is slightly longer, it can easily be moved into an aptly-named utility method (joinLists(listOne, listTwo))
In my opinion #1 is the most important reason to avoid it, closely followed by #2. #3 is usually not that much of a problem, but should not be forgotten.
Because you don't need a separate subclass - you just need to create a new ArrayList of the normal class, and addAll() both lists into it.
Like so:
public static List<String> addLists (List<String> a, List<String> b) {
List<String> results = new ArrayList<String>();
results.addAll( a);
results.addAll( b);
return results;
}
It's evil to create a subclass, that isn't needed. You don't need to extend or subclass behaviour - just change data values.
It's not a bad approach per se, say, in performance or anything like that, but the approach is a bit obscure and when using something like this, you always (say, 99%) have to explain this approach. I think that's one of the biggest reasons not to use this approach, and while typing:
List<String> newList = new ArrayList<String>();
newList.addAll(listOne);
newList.addAll(listTwo);
is a little more typing, it's a bit easier to read, which helps a lot in understanding or debugging code.
In your example it really looks evil and ugly, at least to me - it's difficult to understand what's going on in the code. But there are some patterns of using anonymous classes that people are used to because they see them very often, eg
Arrays.sort(args, new Comparator<String>() {
public int compare(String o1, String o2) {
return ...
}});
I would call the above a best practice case.

What's the difference between anonymous classes in Java and closures?

It looks like anonymous class provides the basic functionality of closure, is that true?
There is almost no difference. In fact the there is an old saying about closures and objects. Closures are the poor man's object, and objects are the poor man's closure. Both are equally powerful in terms of what they can do. We are only arguing over expressiveness.
In Java we are modeling closures with Anonymous Objects. In fact a little history here is that originally Java had the ability to modify the outward scope without the use of final. This works and worked fine for Objects allocated in the local method scope, but when it comes to primitives this caused lots of controversy. Primitives are allocated on the stack so in order for them to live past the execution of the outer method Java would have to allocate memory on the heap and move those members into the heap. At that time people were very new to garbage collection and they didn't trust it so the claim was Java shouldn't allocate memory without explicit instruction from the programmer. In efforts to strike a compromise Java decided to use the final keyword.
http://madbean.com/2003/mb2003-49/
Now the interesting thing is that Java could remove that restriction and make use of the final keyword optional now that everyone is more comfortable with the garbage collector and it could be completely compatible from a language perspective. Although the work around for this issue is simple to define instance variables on your Anonymous Object and you can modify those as much as you wish. In fact that could be an easy way to implement closure style references to local scope by adding public instance variables to the anonymous class through the compiler, and rewriting the source code to use those instead of stack variables.
public Object someFunction() {
int someValue = 0;
SomeAnonymousClass implementation = new SomeAnonymousClass() {
public boolean callback() {
someValue++;
}
}
implementation.callback();
return someValue;
}
Would be rewritten to:
public Object someFunction() {
SomeAnonymousClass implementation = new SomeAnonymousClass() {
public int someValue = 0;
public boolean callback() {
someValue++;
}
}
implementation.callback();
// all references to someValue could be rewritten to
// use this instance variable instead.
return implementation.someValue;
}
I think the reason people complain about Anonymous inner classes has more to do with static typing vs dynamic typing. In Java we have to define an agreed upon interface for the implementor of the anonymous class and the code accepting the anonymous class. We have to do that so we can type check everything at compile time. If we had 1st class functions then Java would need to define a syntax for declaring a method's parameters and return types as a data type to remain a statically typed language for type safety. This would almost be as complex as defining an interface. (An interface can define multiple methods, a syntax for declaring 1st class methods would only be for one method). You could think of this as a short form interface syntax. Under the hood the compiler could translate the short form notation to an interface at compile time.
There are a lot of things that could be done to Java to improve the Anonymous Class experience without ditching the language or major surgery.
As far as they both affect otherwise "private" scoping, in a very limited sense, yes. however, there are so many differences that the answer might as well be no.
Since Java lacks the ability to handle blocks of code as true R-values, inner classes cannot pass blocks of code as is typically done in continuations. Therefore the closure as a continuation technique is completely missing.
While the lifetime of a class to be garbage collected is extended by people holding inner classes (similar to closures keeping variables alive while being rebound to the closure), the ability of Java to do renaming via binding is limited to comply with the existing Java syntax.
And to allow threads to properly not stomp over each other's data using Java's thread contention model, inner classes are further restricted with access to data that is guaranteed not to upset, aka final locals.
This completely ignores the other inner classes (aka static inner classes) which is slightly different in feel. In other words, it touches upon a few items that closures could handle, but falls short of the minimum requirements that most people would consider necessary to be called a closure.
IMHO, They serve a similar purpose, however a closure is intended to be more concise and potentially provide more functionality.
Say you want to use a local variable using an anonymous class.
final int[] i = { 0 };
final double[] d = { 0.0 };
Runnable run = new Runnable() {
public void run() {
d[0] = i[0] * 1.5;
}
};
executor.submit(run);
Closures avoid the need for most of the boiler plate coding by allowing you write just what is intended.
int i = 0;
double d = 0.0;
Runnable run = { => d = i * 1.5; };
executor.submit(run);
or even
executor.submit({ => d = i * 1.5; });
or if closures support code blocks.
executor.submit() {
d = i * 1.5;
}

Categories