Does the compiler optimizes anonymous classes which do not add / override methods? - java

I was wondering if the compiler (ECJ, javac, or you can name your favourite compiler) optimizes anonymous classes which do not add or override methods of it's base class.
For example, for code that looks like this:
Snippet A:
Human h = new Human("John", 30);
h.setX(12.5);
h.setY(15.3);
//..
Eat(h);
I'd always prefer the syntax:
Snippet B:
Eat(new Human("John", 30){
{
setX(12.5);
setY(15.3);
//..
}
});
However I understand that unlike the WITH keyword we have in vb.net, this is not just syntax sugar. What we are telling the compiler to do is to create an anonymous subclass of Human whose constructor consists of the code within the bracers (which is also why we can't use this syntax-sugar for final classes).
The problem now is that I use this syntax-sugar all the time (like for example overriding onclick in UI listeners etc), it's like one of my coding style/habits.
Hence the question:
Does the compiler optimizes this kind of syntax? (i.e. it realised that no anonymous classes needs to be generated, and the performance of Snippet B would be the same as Snippet A)
If the answer to (1) is "no", I was wondering is it (the more-than-expected abundance of anonymous classes due to this coding style) a noticeable impact such that it is highly recommended that for future projects (coding applications for the average mobile device) we should always adhere to the style in Snippet A ?

Yes, it will (always) generate an anonymous class (called Human$1). You can see this by examining the class files that are output. You should have a Human.class and Human$1.class as output.
As for performance implications, there will be two classes (bigger, more work for the VM), references from one to the other (because the anonymous inner class will have a link to the outer class). This may have a effect on performance, I suppose, but only minor. You'd have to test it.
However, it's not particularly idiomatic java to do it this way. The idiomatic way would be to have another constructor.

The compiler will create a separate binary class.
For instance if you have
class Foo{
}
class Bar{
Foo otherFoo = new Foo(){
}
}
In your bin/target directory you will have three classes
Bar.class
Bar$1.class
Foo.class
Here the anonymous subclass is Bar$1.class

Related

Is it possible to generate an inner class of a class to compile with an annotation processor?

I am wondering if it would be possible to generate a class, via an annotation processor, that would be an inner class of a class to be compiled.
For instance, while compiling class A, generate class A$Foo. I wonder if there is a trick that could be used or not. I got the feeling that it might be possible to generate some source that will be compiled in the same byte code as an inner class would. And, at compile/runtime, the JVM would take it for an inner class, and allow accessing outer class private fields.
The idea behind that question, which is not a noobie question, though it may look more or less technical, is to be able to use the private visibility modifier for annotated fields like Dagger, ButterKnife, etc. The private modifier allowing to detect unused fields more easily, whereas package private protection hides them.
Or is there any workaround, any way to get the best of both words ?
Given your use case, no.
An inner class is a normal Java class, living in a different .class file. When compiled, a hidden constructor param is added to the inner class constructor. Private fields in the outer class are made accessible by adding hidden accessor methods in the outer class. All of this happens at compile time.
The JVM has nothing to do with that. If you generate a class that "looks like an inner class of another class", that won't make the outer class fields accessible.
Private visibility is really just a hint to compiler. There is no problem to access those fields at the runtime at all (like I do in my small dependency injector: https://github.com/ko5tik/andject)
And non-static inner classes on android are generally a bad idea as it used to have performance penalty.
At the compile time you could use source generation tool like xdoclet (though it became technically obsolete years ago, but still occasionally used) and generate all the sources you need in advance before compiling them.

In Java, are anonymous inner types detrimental to performance?

Is using anonymous inner types detrimental to performance (CPU utilisation, compiler performance, memory consumption, etc.) as opposed to declaring it explicitly somewhere?
I am using a framework that demands the usage of certain inherited classes, in my case I need the class only a single time and to avoid making the programs flow difficult to follow I'd like to use the anonymous inner type. "object.SetXclass(new ???" will be called often and in any case a new instance of the object inheriting from y needs to be created.
1) explicit class declaration
class x extends y
{
#Override
public void m() { ... };
}
~~
object.SetXclass(new x());
2) anonymous inner type -is this bad for performance?
object.SetXclass(new y()
{
#Override
public void m() { ... };
});
The java compiler compiles anonymous inner classes into their own class files, and the java run time environment then treats the class just as any other class would be treated so there should not be any significant drop in performance. Here are some references on inner class files http://docstore.mik.ua/orelly/java-ent/jnut/ch03_13.htm
An anonymous class saves you having to give the class a name, and pass arguments to a constructor for later use, and it works the same way.
Generally speaking, you should worry about performance, when you have a profiled a realistic test and your measurements indicate you have a problem. Even if you have been performance tuning systems for decades, you can guess at things which might be causing a problem, but when you measure the code you can find that some thing (possibly many things) are far more significant.

Where to put non-public class?

Let's say I have a Java class A, which requires a helper class B. That helper class is only used in A, and has no other purpose. Also, B doesn't need to use A in any way (don't call methods or access fields).
So, the question is: where to put B?
There are the following options:
Static nested class. In my opinion, it just makes code less clear (much more indentation and such).
public class A {
...
private static class B { ... }
}
Non-public class in the same source. I like this option.
public class A {
...
}
class B {
...
}
Non-public class in the separate source. Looks like this option has a little overhead, though.
// A.java
public class A {
...
}
// B.java
class B {
...
}
For now, I prefer the 2nd option. What are your thoughts on it? What is the best practice?
Are there any authoritative sources on it?
I strongly vote for option (1). The idea is, that class B is only needed by class A and option (1) is the only alternative that clearly expresses that intention: class B is part of class A.
You can use a static nested class within A.Better encapsulation since a nested class a way of logically grouping classes that are only used in just one place. does your helper class just contain fields?
was it helpful?
There are no serious disadvantages, but one can certainly figure out at least few including:
Difficult to understand - especially for non-experiences programmers, who may find it difficult to code, enhance, and maintain.
More number of classes - it certainly increases the total number of classes being used by the application. For every class loaded into the memory, JVM creates an object of type Class for it. There may be some other routine tasks, which JVM might be required to do for all the extra classes. This may result in a slightly slower performance if the application is using several nested/inner classes (may be due to a poor design).
Limited support by the Tools/IDE - Nested classes don't enjoy the same support as the top-level classes get in most of the tools and IDEs. This may irritate the developer at times.

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

Consider this (anonymous):
speakBtn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View view) {
mTts.speak(words.getText().toString(), TextToSpeech.QUEUE_ADD, null);
}});
vs. this: (non-anonymous):
class MyOuterClass {
private class MyOnClickListener implements OnClickListener {
#Override
public void onClick(View view) {
mTts.speak(words.getText().toString(), TextToSpeech.QUEUE_ADD, null);
}
}
// later (inside some method)...
speakBtn.setOnClickListener(new MyOnClickListener());
}
Except for the fewer number of lines, is there any other advantage to the anonymous form?
Is there a performance advantage?
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.)
The advantage to non-anonymous is that you can reuse the class. I believe the only reason to use an anonymous inner class is brevity.
Things I like about named inner classes:
They have a name. I find it easier to debug when I see MyOuterClass$MyOnClickListener in a stack trace instead of MyOuterClass$1, which is what you get with an anonymous inner class.
It sometimes helps readability to separate out the actual code for the inner class from the place you're using it. I especially like this if I'm already in a long method or indented more than a level or two.
To comment on your point about performance, anonymous inner classes get compiled into normal classes, so there should be no performance difference.
The advantage is the time you save as a developer for not having to type the extra keystrokes. :)
Oh, and it also prevents you from needlessly having to come up with a new name for everything (which may cause name collisions in some cases).
There is one disadvantage that pops out:
If you need more than one of the same inner class, you pretty much need to use an explicitly defined class. For what you describe, no you don't need one. But you may decide at a later date you need another object that does the same functionality, but is a different object.
The purpose of anonymous classes is make your required class as local. Anonymous classes are used when we are very much sure that a particular class A is the only consumer for a Class B and no where else this B class can be used .Then better we defined that class B as anonymous class inside Named class A. We are writing the required logic within the same class so avoiding the creation of object from outer side. It will easy to maintain in terms of code maintainability. So 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.

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

In some of my projects and in some books was said to not use inner class (anonymous or not, static or not) - except in some restricted conditions, like EventListeners or Runnables - is a best practice. They even were 'forbiden' in my first industry project.
Is this really a best practice? Why?
(I have to say that I'm using them a lot...)
-- EDIT ---
I can't pick a right answer in all these responses: there's part of rightness on mostly all of them: I'll still use inner classes, but I'll try to use them less often !
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.
Cleanliness. It's easier to comprehend code if it's broken into logical pieces, not all mushed into the same file.
That said, I do not consider the judicious use of inner classes to be inappropriate. Sometimes these inner classes only exist for one purpose, so I would then have no problem with their being in the only file in which they are used. However, this does not happen that much in my experience.
Anonymous classes are good to use when doing event based programming especially in swing.
Yes, forbidding inner classes is a useful practice, in that finding out a place forbids them is a good way to warn me off working there, hence preserving my future sanity. :)
As gicappa points out, anonymous inner classes are the closest Java has to closures, and are extremely appropriate for use in situations where passing behaviour into a method is suitable, if nothing else.
As some others said, many times, when you use an anonymous inner class, it is also used on some other places too...
Thus you may easily duplicate inner class code to many places...
This seems not a problem when you are using very simple inner classes to filter/sort collections, using predicates, comparator or anything like that...
But you must know that when you use 3 times an anonymous innerclass that does exactly the same thing (for exemple removing the "" of a Collection), you are actually creating 3 new classes on the java PermGen.
So if everyone use inner classes everywhere, this may lead to an application having a bigger permgen. According to the application this may be a problem... If you are working on the industry, you may program embedded applications that have a limited memory, that should be optimized...
Note this is also why the double curly brace syntax (anonymous innerclass with non-static initialization block) is sometimes considered as an antipattern:
new ArrayList<String>() {{
add("java");
add("jsp");
add("servlets");
}}
You should ask to people who forbids you to use them...
IMHO it all depends on the context...
Anonymous inner classes has benefits in being able to see the fields and variables around the "new" statement. This can make for some very clean design and is a quite nice (but a bit wordy) approach to "how can we make a simple version of lambda statements".
Named inner classes has the benefit of having a name, hopefully telling, which can be documented in the usual way, but which is tied together to the surrounding class. A very nice example is the Builder pattern, where the inner class is responsible for providing state for the initialization process instead of having numerous constructors. Such builders cannot be reused between classes, so it makes perfect sense to have the Builder tied closely to the parent class.
I suggest being cautious when using it if it needs a method parameter. I just found a memory leak related to that. It involves HttpServlet using GrizzlyContinuation.
In short here is the buggy code:
public void doGet(HttpServletRequest request, final HttpServletResponse response){
createSubscription(..., new SubscriptionListener(){
public void subscriptionCreated(final CallController controller) {
response.setStatus(200);
...
controller.resume();
}
public void subscriptionFailed(){
...
}
public void subscriptionTimeout(){
...
}});
}
So since the listener is kept by the subscription the HttpServletResponse is also kept in case the listener needs it (not obvious). Then the HttpServletResponse instance will be release only if the subscription is deleted. If you use an inner class that gets the response in it constructor it can be set to null once the call was resume releasing memory.
Use them but be careful!
Martin
One item that is not mentioned here is that a (non-static) inner class carries a reference to it's enclosing class. More importantly, the inner class has access to private members of it's enclosing class. It could, potentially, break encapsulation.
Don't use an inner-class if you have an option.
Code without inner classes is more maintainable and readable. When you access private data members of the outer class from inner class, JDK compiler creates package-access member functions in the outer class for the inner class to access the private members. This leaves a security hole. In
general we should avoid using inner classes.
Use inner class only when an inner class is only relevant in the
context of the outer class and/or inner class can be made private so that only outer class can access it. Inner classes are used primarily to implement helper classes like Iterators, Comparators etc which are used in the
context of an outer class.
Certain frameworks, like Wicket, really require anonymous inner classes.
Saying never is silly. Never say never! An example of good use might be a situation where you have some legacy code that was written by someone where many classes operate directly on a Collection field, and for whatever reason, you cannot change those other classes, but need to conditionally mirror operations to another Collection. The easiest thing to do is to add this behavior via an anonymous inner class.
bagOfStuff = new HashSet(){
#Override
public boolean add(Object o) {
boolean returnValue = super.add(o);
if(returnValue && o instanceof Job)
{
Job job = ((Job)o);
if(job.fooBar())
otherBagOfStuff.add(job);
}
return returnValue;
}
}
That said, they can definitely be used like a poor man's closures.
Inner classes are appropriate when trying to emulate multiple inheritance. It is similar to what happens under the hood with C++: when you have multiple inheritance in C++, the object layout in memory is actually a concatenation of several object instances; the compiler then works out how the "this" pointer shall be adjusted when a method is invoked. In Java, there is no multiple inheritance, but an inner class can be used to provide a "view" of a given instance under another type.
Most of the time, it is possible to stick to single inheritance, but occasionally multiple inheritance would be the right tool to use, and this is the time to use an inner class.
This means that inner classes are somehow more complex than usual classes, in the same way that multiple inheritance is more complex than single inheritance: many programmers have some trouble wrapping their mind around that concept. Hence the "best practice": avoid inner classes because it confuses your coworkers. In my view, this is not a good argument, and at my workplace we are quite happy to use inner classes when we deem it appropriate.
(A minor drawback of inner classes is that they add one extra level of indentation in the source code. This is a bit irksome at times, when one wants to keep the code within 79 columns.)
Anonymous inner classes are often used when we need to implement interface with one method, like Runnable, ActionListener and some other.
One more great appliance of anonymous inner classes is when you don't want to make a subclass of some class but you need to override one (or two) of its methods.
Named inner classes can be used when you want achieve tight coherence between two classes. They aren't so useful as anonymous inner classes and I can't be sure that it's a good practice to use them ever.
Java also has nested (or inner static) classes. They can be used when you want to provide some special access and standard public or default access levels aren't enough.
Inner classes are often used to "pass a behavior" as a parameter of a method. This capability is supported in an elegant way by other languages with closures.
Using inner classes produces some not elegant code (IMHO) because of a language limitation but it's useful and widely used to handle events and blocks in general with inner classes.
So I would say that inner classes are very useful.
yes it is good to use them, when you are trying to keep a class cohesive, and the classes should never be instantiated from outside their context of the outer class, make the constructors private and you have really nice cohesive encapsulation. Anyone that says you should NEVER use them doesn't know what they are talking about. For event handlers and other things that anonymous inner classes excel at they are way better than the alternative of cluttering up your package namespace with lots of event handlers that only apply to a specific class.
I tend to avoid non-static inner classes for the reasons given by other posters. However I have a particularly favourite pattern where a non-static inner class works very effectively: Lazy loading stateful classes.
A typical lazy loading stateful class is constructed with an entity ID and then on demand can lazily load additional entity information. Typically to lazily load the additional information we will require dependencies. But dependencies + state == anti pattern!
Non-static inner classes provide a way to avoid this anti-pattern. Hopefully the following simple example illustrates this better than words can:
/*
* Stateless outer class holding dependencies
*/
public class DataAssembler {
private final LoadingService loadingService;
#Inject
DataAssembler(LoadingService loadingService) {
this.loadingService = loadingService;
}
public LazyData assemble(long id) {
return new LazyData(id);
}
/*
* Stateful non-static inner class that has access to the outer
* class' dependencies in order to lazily load data.
*/
public class LazyData {
private final long id;
private LazyData(long id) {
this.id = id;
}
public long id() {
return id;
}
public String expensiveData() {
return loadingService.buildExpensiveDate(id);
}
}
}
Worth noting that there are many other patterns beyond the above example where inner classes are useful; inner classes are like any other Java feature - there are appropriate times where they can be used and inappropriate times!
When use or avoid inner class in Java?
The inner class has the following characters.
Anyway the .class file is separated as OuterClassName$InnerClassName.class
The class name and the class file name of the inner class always contain the outer class name.
The above characters disclose this fact. The outer class name is the mandatory information for the inner class.
We can derive this result from the fact. The inner class is good to be defined when the outer class is mandatory information of the inner class.
The characters of the inner class make developers sometimes annoying to debug. Because it forces the developer to know the outer class name with the inner class.
Suggestion
It can be a design principle to avoid defining the inner class except when the outer class name is the mandatory information of the inner class for the above two reasons.

Categories