Can someone explain the difference between anonymous classes, nested classes and private classes in Java? 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.
By anonymous classes I mean those declared inline in a function in that weird Java way. This is often seen in examples of Swing code where you write a button handler inline with the declaration of it. I don't really like anonymous classes because you get those funny MyClass$1.class files and more often than not you'll have to refactor later when it turns out you want to make the anonymous class a singleton or need a handle to it or something. I also just don't like the way you're attaching a handler in the form of something you just made up whilst in the middle of another function call. It just makes me feel weird. :-)
Private classes are the ones you write at the bottom of your file completely outside the declaration of your public class. I prefer private classes just because they make sense in other languages where there isn't a strong 1:1 relationship between a source file and a class. I don't get that weird feeling and I know (or I think I know) how a Java compiler will handle the declaration of that class.
Nested classes are ones written inside the squigglies of your public class. I really don't know what a nested class means compared to the other two. :-)
First to correct some terminology.
A private class is a class that is declared with the access modifier
private
. This modifier can only be used on a nested class, so private classes are a subset of nested classes.Classes that "you write at the bottom of your file completely outside the declaration of your public class" are actually package private. And this is because of their access / visibility ... not the fact that they are in the same file some other class.
(Not withstanding that you like doing this, it is generally accepted that it is a BAD IDEA to put more than one top-level class in one source file. It is liable to break tools and IDEs, for a start. Source: http://geosoft.no/development/javastyle.html.)
So what is the difference between them?
A package private class is the same as an ordinary
public
orprotected
class, except that it is ONLY visible to other classes in the same package.A nested classes is a
static
class that is declared within another class. It behaves for all intents and purposes the same way as a non-nested class. In particular, instances can be created independent of any enclosing class instances.A local inner class is a non-
static
class that is declared within another class. An instance must be created in the context of an instance of the enclosing class, and can access all members of that instance.An anonymous inner class is functionally similar to a local inner class, except that:
final
), andThe anonymous inner class syntax combines declaration and instantiation, and is designed to make it easy to write light-weight callbacks.
What about performance?
What about acceptability?
Nested classes (including private ones) and the two forms of inner classes are all acceptable, and have their uses. (Obviously some are more appropriate than others, depending on the use-case. But you could say that about every Java construct.)
The form that you mislabeled as "private" (where you put multiple top level classes into one source file) is generally thought to be a bad idea.
Anonymous classes are for instance the Runnable in
Nested classes look like
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 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:
Gets compiled into:
As for runtime cost, private and public classes are the same. In theory there is a difference, because the JVM could inline methods from a private class more easily, but that's theory.
Nested classes: there are two kind, static and non-static. This actually is a relatively big difference: the static class is like a private class, and the non-static class has a pointer (reference, whatever you want to call it) to the parent object. Which means it needs more memory, so if possible use static nested classes. Otherwise, nested classes are as fast as private or public classes. From a non-static nested class you can access the parent object (that's why it has a reference to the parent), but be careful when accessing private fields, because this is done using special hidden anonymous functions (Eclipse will give you a warning).
If you really want to understand all the differences, you should use
javap
to decompile the class.