Anonymous inner classes: declared as instance variables vs creating on the fly - java

I am refactoring a class with a public facing interface and thinking about the usage led me to ask:
What is the difference between declaring the following within some larger class (as an instance variable):
private final OnClickListener mButtonOnClickListener = new OnClickListener() {
#Override
public void onClick(View view) {
//some codes
}
};
vs declaring as an anonymous inner class as follows (on the fly):
private void someFunctionInClass() {
someOtherFunctionThatTakesAnOnClickListener(new OnClickListener() {
#Override
public void onClick(View view) {
//some codes
}
});
}
More specifically, is the former still considered an anonymous inner class? I read in this answer that an anonymous inner class
is one that is created AND defined within the body of another class' method
The first example I gave is created and defined within the body of another class but not within another class' method as the second one is. Is it still an anonymous inner class? Furthermore, what is the accepted practice for one vs. another? Is it more efficient to declare (what I think is still) an anonymous inner class as an instance variable because new objects don't need to be recreated?

Both of these are anonymous classes. Other than scope there is not much difference. But below is a link that can be used in deciding which to use from
Local class:
Anonymous class:
Nested class:
Lambda expression:
http://docs.oracle.com/javase/tutorial/java/javaOO/whentouse.html
I hope it helps.

Those are both anonymous classes. In the first one, you can reuse it, but both are just objects that are created. An anonymous class is necessarily an inner class, and can access any fields of the enclosing class.
I think you may be getting anonymous classes confused with inner classes and static nested classes, which have distinct differences.

Both are anonymous classes. Taking the example of a listener, if you intend to use the same listener for two components you can have an instance variable for that else you can directly attach it to the component. So it depends on the requirement.
But mostly its a sort-of one-time use, that is, you avoid creating instance for that. If you intend to reuse it, its better you create a separate class for that.

Both are anonymous classes. An anonymous class is a constructor (new ClassName()) followed by a class body ({...}).

In your examples, in both cases you have created anonymous inner class. That it "new OnClickListener() {" I think it does not have overhead since its getting resolved at compile time. People use it all the time.

Related

What are the purposes of inner classes

I am reviewing the concept of inner classes in java. so far from what I've understood and applied java inner classes has a link or access to the methods and fields of its outer/ enclosing class.
My Question:
When should create or define an inner class?
are inner classes considered to be called as "Helper classes" ?
What are the indicators for you to make an inner class and what's their other purpose?
Inner classes are best for the purpose of logically grouping classes that are used in one-place. For example, if you want to create class which is used by ONLY enclosing class, then it doesn't make sense to create a separate file for that. Instead you can add it as "inner class"
As per java tutorial:
Compelling reasons for using nested classes include the following:
It is a way of logically grouping classes that are only used in one
place.
It increases encapsulation.
It can lead to more readable and maintainable code.
A classic use for an inner class is the implementation of an iterator inside a container (ArrayList, for example - look for class Itr). All the container wants to expose to the rest of the world is an Iterator. However, it has to create some concrete implementation of that iterator, possibly familiar with the internals of the container. Using an inner class hides the implementation, while keeping it close to the container's implementation. And being inner (i.e. non-static), it is bound to a specific instance of that container, which lets it access private container members.
There are a few types of inner classes - non-static nested class, local classes and anonymous classes. Each one has a somewhat different purpose, so when asking about an inner class, you should specify what kind are you talking about.
Assuming you're referring to non-static inner classes, I'd say the reason to use them is the same as using regular classes (namely abstraction and dividing code into logical units), but there's no reason to make this use of classes visible to the rest of the world. You can also make nested classes public, of course, in which case you'd make them nested instead of independent in order to express their tight relation with the outer class.
See the Java tutorial for the main reasons.
If by "helper class" you mean something for internal use only, then no, not necessarily. You might want to do something like
class Outer {
private static class Inner implements InterestingInterface {
// whatever
}
public InterestingInterface make_something_interesting() {
return new Inner();
}
}
Here, Inner is not a "helper class" in the sense that the outside world does get to see instances of it, but its implementation is entirely hidden -- the outside world only knows it gets some object that implements InterestingInterface.
As a general rule, objects should be designed for a single responsibility (Highly cohesive). In other words, any object designed well, should perform a single coherent task. This would be considered best practice for object orientated design.
Sometimes, however, a developer may design a class that requires a separate specialized class in order to work. This separate specialized class could be considered a helper class.
If the helper class is not used by any other class, then it would be considered a prime candidate as an inner class
As elicited by ncmathsadist above, an example of inner class use would be in the implementation of Event handlers.
For example, in designing a graphical user interface (GUI), a developer may have created a button that performs a particular task after the user presses it.
The button would need an event handler which listens for when that particular button is pressed.
In this case, creating the event handler for the button as an inner class would be best practice as the inner class would not be utilized anywhere else other than with the specific button within the GUI class.
One purpose of inner classes is to attach listeners. For example, suppose you have a JMenuItem. You can make it quit your app as shown in this code:
JMenuItem quitItem = new JMenuItem("Quit");
quitItem.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e)
{
//cleanup code before exiting
System.exit(0);
}
});
You may also want a class to have access to outer class state variables which is entirely subservient to that class. For example, consider writing a simple color calculator. It might have a text area into which you type a hex code. When you hit enter, you want a JPanel to display the color. Here is a crude outline of what you might do.
public class ColorCalc extends JPanel implements Runnable
{
Color displayedColor;
JTextArea colorEnterArea;
public ColorCalc()
{
displayedColor = Color.white
colorEnterArea = new JTextArea();
}
public void run()
{
//build GUI here
}
public static void main(String[] args)
{
ColorCalc cc = new ColorCalc();
javax.swing.SwingUtilities.invokeLater(cc);
}
//subservient inner class with access to outer class state variable.
class ColorPanel extends JPanel
{
public void paintComponent(Graphics g)
{
g.setColor(displayedColor);
g.fillRect(0,0,getWidth(), getHeight());
}
}
}
This is a style question. Anything that can be done with an inner class can also be done as a as series of external classes. Inner classes are especially useful for classes that are lightweight or tightly bound to the enclosing class. For example, a comparator is frequently both these things. It needs intimate knowledge of the implementation of the class, and may only be a few lines long. It may be an ideal candidate as an internal class.
If you find that there is enough code which could be better done by class as class provides us to specify stats and
behavior with fields and methods and you don't want this class needs to be used outside of enclosing class. you should use inner class.
Here the inner class is hidden from the outside world.
Inner class can access the private member of enclosing class which provides us encapsulation.
Let me give example..
Suppose you want to set the gear to cycle and you have a business rule like there are only up to 6 gears.
So you can create Inner Class Cycle which would have a method to set the gear.
That method has some validation which are checked before setting gear.like the cycle is running...gear number is less than 6...
best example is event handling code uses inner classes(sometimes anonymous inner classes) to create events and listeners without creating separate Event Object and Event Listener classes for your event..
The inner class used for grouping classes logic, for example, if you have class B and this class used only at class A, So it is better to put class B as an inner class at class A, as this will give readability and reusability for your code.
Happy code :)
Adding from my personal notes, for future visitors:
Sources: https://docs.oracle.com/javase/tutorial/java/javaOO/whentouse.html
Lets say you have a type and its a class, called OuterClass, in a package called "com.custom.classes".
Then here is how you begin to need an inner class or static class:
Case 1:
you need to package a group of classes
but also kind of need certain global variables exposed to all these classes at that package level
you understand you can do no such things with packages but realise that you could achieve this with inheritance, where the parent class members can act as global variables that become available for all of its child class instances.
but you don't like the idea that you need to inherit the parent class and also that you need to instantiate the child class to access the global variables. Thats like asking to buy a coffee shop in order to have a coffee.
and so you realise that you can create an OuterClass with the static members and house all the classes in this OuterClass as inner class or static class as needed and lo! The OuterClass static members become available as global variables for these nested classes and you could even access them without instantiating them.
This code should explain better
public class InnerClassTester{
public static void main(String []args){
// without the need to instantiate any class
// static class without instantiation
System.out.println(OuterClass.NestedStaticClass1.incrGlobalNum()); // outputs 1
// static class instantiated
OuterClass.NestedStaticClass2 koolObj = new OuterClass.NestedStaticClass2();
// works with instantiation as well
System.out.println(koolObj.incrGlobalNum()); // outputs 2
// inner classes always need to be instantiated
// and they can only be instantiated from within an instance of outer class
// think of them as instance member of outer class and this would make sense
OuterClass.NestedInnerClass1 koolObj2 = new OuterClass().new NestedInnerClass1();
// works with inner classes as well
System.out.println(koolObj2.incrGlobalNum()); // outputs 3
}
}
class OuterClass{
// global variable thats only accessible for select classes (or nested classes)
// we also learn a purpose for private static fields
private static int privateGlobalValue = 0;
// classes to be grouped
// static class
public static class NestedStaticClass1{
// no need to instantiate this class to access/update the global value
public static int incrGlobalNum(){
return ++privateGlobalValue;
}
}
public static class NestedStaticClass2{
// instantiate and still manipulate the global value
public int incrGlobalNum(){
return ++privateGlobalValue;
}
}
// inner class
public class NestedInnerClass1{
// instantiate and still manipulate the global value
public int incrGlobalNum(){
return ++privateGlobalValue;
}
}
}
Does this remind you of closures in Javascript ? :)
Most applications of nested classes see it being applied on basis of design decisions. What that means is, every case of a nested class can be replaced with other designs.
But having said that, it is also true that we can also replace the inheritance pattern with composition pattern (and it is gaining momentum lately) although an inheritance pattern is definitely better when the dependencies between the classes is so much so that composing the dependencies entirely would be ugly.
Case 2:
you need to implement 2 interfaces, IShark and IMosquito, with the same signature, a public bite method, on the OuterClass.
but you want to display 2 different messages since a shark's bite is a tad different from that of a mosquito's.
however you know that's not possible since only one bite method can be implemented
you know you can create 2 different classes in the same package that implement either interfaces and also implement separate bite methods and have them composed in OuterClass.
but you wanted to get it done within OuterClass because it was your design decision to encapsulate the bite behaviour within it, maybe because there was a dependency on a private variable within the class.
soon you realise you can implement both the interfaces via private static inner classes and make it appear to the outside world as though it was composed.
Take a look at this code:
// no additional classes in the package
public class InterfaceTester{
public static void main(String []args){
// same class returns 2 instances - both compliant to
// either interfaces and yet different output
IShark shark = OuterClass.getSharkInstance();
System.out.println(shark.bite()); // outputs "Die fast bosedk!"
IMosquito mosquito = OuterClass.getMosquitoInstance();
System.out.println(mosquito.bite()); // outputs "Die slow bosedk!"
}
}
interface IShark{
public String bite();
}
interface IMosquito{
public String bite();
}
class OuterClass implements IShark{
// dependency of inner class on private variable
private static String dieSlow = "Die slow bosedk!";
private static String dieFast = "Die fast bosedk!";
private static OuterClass outerInst;
private static InnerClass innerInst;
// private constructor to stop regular instantiation
private OuterClass(){}
// get a shark !
public static IShark getSharkInstance(){
return outerInst != null ? outerInst : new OuterClass();
}
// get a mosquito !
public static IMosquito getMosquitoInstance(){
return innerInst != null ? innerInst : new InnerClass();
}
// an implementation of bite
public String bite(){
return dieFast;
}
// inner class that implements the second interface
private static class InnerClass implements IMosquito{
// different implementation of bite
public String bite(){
return dieSlow;
}
}
}
These kind of design decision cases are numerous and all of the answers above list several such cases. So it would not be wrong to think that this feature was introduced more as a new pattern than as a feature or functionality.
Conceptually inner classes can be used to represent types in the universe that would not exist without that parent type. In other words, with a language that allows inner classes, the types are all 'type definers'. A type can then be considered something that explicitly or implicitly defines new types.
For example, imagine we have a universe where "Food" can be applied to anything. Even itself. Food is a fundamental concept in our universe. We introduce a subclass of Food called Meat. Without that concept, there is no such thing as "Meat Eater". So we can (note 'can') define a nested type "Meat.Eater" (which could implement an IEater interface) and define animals as being a containment structure of lists of different IEaters.
Once we remove Meat from the universe, Meat Eater disappears to.
This same philosophy applies neatly to more abstract and technically useful arrangements such as Mementos in the Memento Design Pattern , a configuration object defined as a nested class, and other type-specific behaviours or structures.
It also increases encapsulation because inner classes can be declared private.
I would just consider that this is just a feature of language. I would not recommend to use it if we adopt OOD and obey the SOLID principle.

Why we call adding a listener to button directly as inner class?

If we add event listener to a button in java like this :
btn.setOnClickListener(new OnClickListener(){
public void onClick(View v)
{
// Do smoething
}
});
this is called we are using inner-class, I have problem in understanding the the concept of inner class
isn't the inner class declared like this ?
class AOuter{
int a=5;
class BInner{
// do smothing
}
}
The click listener is an anonymous inner class, the other one is simply an inner class. They are both types of nested classes
The class you have provided to setOnClickListener cannot be instantiated elsewhere. It lives just as an argument to that function while the class defined in the second code segment is nested and it can be instantiated normally.
#Andrejs is correct. The reason for people using anonymous inner class to add the listener usually is because this is a one time thing and you won't reuse that action/listener. However, if that listener/action is planned to be reused, one should explicitly define it to make it reusable.

Should we use anonymous classes for OnClickListeners or inner named classes?

I have lots of buttons in my Activity, I have the following questions:
Should I create multiple inner anonymous classes for OnClickListeners for each button, like below:
private View.OnClickListener mShuffleListener = new View.OnClickListener() {
public void onClick(View v) {
/// task to do
}
};
Or should I go for a named inner class and add an if condition to check which click listener was called.
Which one is better to save memory resources?
Which one is cool to save mem resources?
It will make hardly any difference. At most 1 word ... and that is comparing a static inner class with a (non-static) anonymous class. A saving as small as that is not worth the code readability / maintainability penalty, even (IMO) if you've got a hundreds of these buttons.
There are three ways to handle event. Please have a look on the following link
http://tseng-blog.nge-web.net/blog/2009/02/14/implementing-listeners-in-your-android-java-application/
See the following to know the use of anonymous class and inner class
anonymous class
Use anonymous inner classes if you want the code not to be used
anywhere else (this class is being used just here and nowhere else.)
inner class
inner class code can be used (if only by the class that created it if
made private). If you see a named inner class, someone might think
it'd be used in multiple places in the class.
I generally prefer a more subtle approach which makes the code easier to read when using onClick listener
There is a property called onClick for almost all the widgets in the properties menu(also available in the layout xml), there you can write a method name Ex xyz
now go to your java source file there you simply write a method
Ex
public void xyz(View v)
{
//your code goes here
}
and you are done .Also if you really wanna use inner classes then go with anonymous ones if memory is you concern(each reference stored takes 8 bytes of memory in java if its a reference type which in this case it is).
hope this helps..please do ask if you need more clarification
If all buttons have similar functionality that differs only in a parameter that is identifiable, it is better to create one listener and assign it to all buttons.
The location of the listener is dependent of the scope of variables it need to use. If it needs to use some method variables, it should be created inside the method, if it uses a class members, it should be created inside the class.
For example, if you have ten buttons that each should start a different activity, you can create a map of views and activities, and in the listener fund the appropriate activity to start:
Map<View, Class<?>> viewActivityMap = new HashMap<View, Class<?>>();
// fill it somewhere
// in onCreate
View.OnClickListener listener = new View.OnClickListener() {
#Override
public void onClick(View v) {
Class<?> classToStart = viewActivityMap.get(v);
Intent intent = new Intent(YourActivity.this, classToStart);
startActivity(intent);
}
}
button1.setOnClickListener(listener);
button2.setOnClickListener(listener);
button3.setOnClickListener(listener);
In case of listeners, the only real reason I see to create an inner class, is if you want to create a constructor that receives parameters that are different from the implemented class/interface constructors.

This Way of Writing?

Though i have often come across,i dont understand this way of writing code:
Runnable r=new Runnable() {//<----- (braces start here?)
public void run() {
System.out.println("Hello");
}
}; // ?
What is this?
Please explain very clearly.
That's an anonymous inner class. It's creating an implementation of the Runnable interface using code within the braces. As well as implementing interfaces, you can extend other classes. The nice aspects are that you can do this without explicitly creating a separate class, and you can also refer to final local variables (including parameters) within the body of the anonymous inner class.
See the Java tutorial for more details, or just search for "anonymous inner class" for loads of related pages.
As mentioned by others, what is being created here is an anonymous inner class. Specifically, the person who wrote the code is saying:
Instead of an instance of the Runnable class, I want to create a subclass that overrides the "run()" method and create an instance of that. Its not worth my time to create a named subclass, since I'm only going to create this one instance. Instead, just override the method and return the subclass instance I need.
That's an anonymous class declaration - basically, a class that implements the Runnable interface, declared and instantiated inline as an anonymous nested class.
Note that you can also declare anonymous subclasses the same way:
Object o = new Object(){
public String toString(){ return "boo!" };
}
Also note that you can use variables of the enclosing method inside the anonymous class code, but only if the variables are final (because the anonymous class actually gets a copy of the variable).
I would start with these http://www.google.co.uk/search?q=anonymous+classes+tutorial 23 million results.
Basically, it allows you to define an implementation or a subclass without having to create a fully formed class defintiions.
EDIT: For your own interest, see if you can figure out what this does.
Map<String, String> map = new LinkedHashMap<String, String>() {{ // two brackets
put("a", "aye");
put("b", "bee");
put("c", "see");
put("d", "dee");
put("e", "ee");
put("f", "eff");
}};
It's so called 'anonymous class'.
You can do this:
class MyRunnable implements Runnable{
public void run() {
System.out.println("Hello");
}
}
Then:
Runnable r = new MyRunnable();
And achieve the same thing. However, the MyRunnable class that you created is never needed in any other part of your code. So creating a named class is not necessary. The code that you wrote on the other hand is creating an anonymous inner class such that the implementation of the class is precisely where it is needed. It will not be accessible rom anywhere else in the code but that is the idea, you do not need it anywhere else.

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.

Categories