Learn Java for Android Development: More On Inner Classes

This quick lesson discusses a number of tips for working with inner classes in Java. This lesson is part of an ongoing series of tutorials for developers learning Java in order to develop Android applications.

What are (Anonymous) Inner Classes?

In Java, classes can be nested within one another in order to organize data and functionality in an orderly fashion. Anonymous inner classes are basically developer shorthand, allowing the developer to create, define, and use a custom object all in one go. Anonymous inner classes are frequently used in Android to define handlers for controls, define and launch new threads, and create and return custom objects in methods without cluttering code with unnecessary setup.

For a thorough discussion of nested and inner classes, including anonymous inner classes, see our tutorial called Learn Java for Android Development: Inner Classes

Accessing Outside Variables with the Final Keyword

Sometimes you want to access information available outside of the inner class. Consider the following example. You’ve got a screen with two controls: a Button and a TextView. Each time the user clicks on the Button control, the TextView control is updated with the current time. Within the Activity class associated with this layout, you could implement this functionality as follows:

The above code will run and behave as expected. However, let’s say you really wanted to declare the TextView control outside the inner class and use it for other purposes as well. Perhaps you’d try to do this instead:

Unfortunately, this won’t compile. Instead, you’ll get the compile error “Cannot refer to a non-final variable myTextview inside an inner class defined in a different method”. As the error suggests, what you need to do is make the TextView variable final, so that it is accessible within the inner class’s onClick() method:

This code will indeed compile and run as expected.

Working with Final Variables in Java

By making the TextView variable final in the previous example, you’ve made it available to the anonymous inner class (or any inner class defined within its scope, for that matter). Here are some other things to know about final variables:

  • You cannot change the value (r-value) of a final variable. For example, if you tried to assign the myTextview variable to another control within the onClick() method of the inner class, you would get the compile error “The final local variable myTextview cannot be assigned, since it is defined in an enclosing type.”
  • You can call a final variable’s methods, provided you have access. This is what allows us to make the call to the TextView’s setText() method. This does not change the value of the variable myTextview, it simply changes what is displayed to the screen—a subtle but important difference. (The reason for this is simply that the reference to the object can't change, but the object itself can change through its methods.)
  • A final variable’s value need not be known at compile time, whereas a static variable is known at compile time.
  • The final keyword is often paired with the static variable (a field or variable tied to all instances of a class, instead of a single instance) to create a constant for use within your application, as in: public static final String DEBUG_TAG, used for LogCat logging purposes throughout your Activity.

Inner Classes and the "This" variable

In Java, you can use the special this reference to refer to the specific instance of an object. So what happens when you have a class with an inner class, or, for that matter, an anonymous inner class? Well, the inner class can access the special this instance of the enclosing class, and it has a this reference of its own as well. To access the this instance for the inner class, simply use the this syntax. To access the this instance of the enclosing class, you need to tack on the name of the enclosing class, then a dot, then this. For example:

Take a look at the full implementation of the anonymous inner class, as discussed above, in the full context of its enclosing class, here called ClassChaosActivity:

The log output for the button click proceeds as follows:

As you can see, the this keyword on its own refers to the “closest” class—the inner class. Although the inner class is anonymous, Java does give it a number ClassChaosActivity$1 to keep track of it. While not useful to developers per se, this shows that the anonymous inner class is treated like any other class internally. Meanwhile, we access the enclosing class instance using the ClassChaosActivity.this syntax.

Conclusion

In this quick lesson you have learned several tips to help you use inner classes and anonymous inner classes more skillfully. You learned that inner classes can access variables declared outside their scope, provided the variables are marked as final and therefore unchangeable. You also learned about the special syntax related to the this keyword when it comes to accessing inner class instance data as well as its enclosing class instance data.

About the Authors

Mobile developers Lauren Darcey and Shane Conder have coauthored several books on Android development: an in-depth programming book entitled Android Wireless Application Development and Sams TeachYourself Android Application Development in 24 Hours. When not writing, they spend their time developing mobile software at their company and providing consulting services. They can be reached at via email to [email protected], via their blog at androidbook.blogspot.com, and on Twitter @androidwireless.

Need More Help Writing Android Apps? Check out our Latest Books and Resources!

Buy Android Wireless Application Development, 2nd Edition  Buy Sam's Teach Yourself Android Application Development in 24 Hours  Mamlambo code at Code Canyon

Tags:

Comments

Related Articles