Sunday, April 08, 2012

Inner Classes in Java


Overview

A class that is defined inside another class is called an inner class. Inner classes have been available in Java since 1.1. 

While it's possible to implement most, if not all, of the functionality provided by inner classes without using them, they do have some important benefits:
  • Some design patterns are easily implemented with inner classes, e.g., adaptor, enumerator and state patterns.
  • Inner classes provide an elegant and convenient way of implementing callback mechanism.
  • Closures (with some restrictions) can be implemented in Java using inner classes.
  • Multiple inheritance can be emulated by using inner classes.

Tip: Inner classes are implemented fully in the Java compiler.

Note: An inner class cannot be instantiated without an instance of the enclosing class.

Note: Inner classes cannot define static members. The only exception to this rule is compile time static constants that are marked final.

Note: A class defined inside another class that is marked static (i.e., a static member class) is not an inner class.

Types of Inner Classes

Inner classes are of the following types:


Member Inner Classes

A member inner class is defined inside another class the same way a member field or method is defined, with any of the supported access modifiers. 

public class Outer {
     …

     public class Inner {
          … 
     }
}

Instantiating a member inner class is a little different than instantiating a regular class. The general syntax to create an instance of a member class is as follows:

outerClassReference.new MemberClassConstructor();

Give the class definitions above, here's how you'll instantiate an instance of the Inner class in the context of an instance of the Outer class:

Outer outer = new Outer();
Outer.Inner inner = outer.new Outer();

Warning: Note that you always use the constructor name for the member inner class after the new operator. Since the new operator is already qualified with the enclosing instance reference (as in out.new), the Java compiler figures out the fully qualified name of the enclosing class name automatically. It is a compile-time error to qualify the inner class constructor with its outer class name while creating an instance of an inner class.


Local Inner Classes

A local inner class is defined inside a code block (method, instance initializer or static initializer) with its
scope limited to the enclosing block. Because the scope of the class is defined by the enclosing block, it cannot use any of the access modifiers.

public class Outer {
     … 
     public static void main(String[] args) {
          class Inner {
               … 
          }
          
          … 
     }
}

A local inner classes can be instantiated just as any other class by simply new'ing it up.

Note: In order for a local inner class to use a variable from its enclosing scope, the captured variable must be declared final or the compiler will complain.


Anonymous Inner Classes

An anonymous class is the same as a local inner class except that it doesn't have a name. An interesting side effect of an anonymous class not having a name is that it cannot declare a constructor. An anonymous class is a one-shot class that's defined (by implementing an interface or extending a class) and instantiated at the same time as follows:

public lass Task {
     public void execute() {
          Thread thread = new Thread(new Runnable() {
               … 
          });
          thread.start();
     }
}

An anonymous inner class is defined and instantiated at the same time.

Note: In order for a local inner class to use a variable from its enclosing scope, the captured variable must be declared final or the compiler will complain.

Accessing Enclosing Class Members

An inner class has access to all instance members (fields and methods) of its enclosing class. When accessing non-hidden members, i.e., members defined only in the enclosing class, you can access them directly. However, if the inner class hides a member of the enclosing class, you must qualify access to the enclosing class member using the Outer.this.member syntax. An instance variable from the enclosing class can be access in any of the following ways if it's not hidden:
  1. Simple name,
  2. Simple name qualified with the keyword this, or
  3. Simple name qualified with the enclosing class name and the keyword this -- e.g. Outer.this.member
However, when accessing a hidden variable, you must qualify the this keyword with the name of the outer class.

Here's a quick example:

public class Outer {
     private int value;

     public class Inner {
          private int value;

          public void printValue() {
               System.out.println("inner value: " + value);
               System.out.println("inner value: " + this.value);
               System.out.println("outer value: " + Outer.this.value);
          }
     }
}

Summary

Inner classes are a powerful Java feature that affords programmers to achieve things as multiple inheritance (emulated) and closures. It also provides an elegant mechanism for implementing certain design patterns. An inner class can be defined as member of another class, within a local scope (method, instance and static initializers), or as anonymous implementation of a given interface or class. When using inner classes pay special attention to some of the restrictions they place on what they can define and what/how they can access members of the enclosing type.

Saturday, September 24, 2011

How to Pin Cygwin Bash Shell to Taskbar and Start Menu in Windows 7

Cygwin is a collection of tools which provide a Linux look and feel environment for Window mainly via the Bash shell. I love it because it gives me the ability to use my Bash skills in Windows. Details of the project can be found at http://www.cygwin.com/.

After you install the project on Windows 7, you'd typically want to pin the "Cygwin Bash Shell" launcher (link) either to the Taskbar or Start Menu (or both). However, when you right-click the icon to do so, you'll notice none of the said options are available.


At the very least, you'd expect that the launcher would make it into the "frequently used programs" list of the Start Menu, assuming you use it frequently like I do. But you'll be disappointed here too as that never happens regardless of how frequently you use the program.

The issue is the specified target for the launcher. If you right-click the Cygwin Bash Shell launcher, and select Properties, here's what you get.


As highlighted in the image above, because the target is a batch (.bat) file, Windows doesn't give you options to pin it to the Taskbar and Start Menu in addition to not listing it as a frequently used program.

Luckily, the solution is simple. All you need to do is enter the following in Target: and click OK.

%comspec% /K "C:\cygwin\Cygwin.bat"

Of course, I am assuming that you've installed Cygwin to the default location, i.e., C:\cygwin. If you've installed it to a different location, you'll need to update the path accordingly. After you're done, properties of the launcher should look like the following:


Now if you right click the launcher again, you'll see that you can pin it to the Taskbar and Start Menu.



Not only that, Windows will now list the program as a frequently used one, if you use it frequently, giving you direct access to its launcher for quick access.


Hope that helps.

Cheers!

Wednesday, October 13, 2010

How to dynamically number rows in a SELECT Transact-SQL statement

In a Microsoft Support article available at http://support.microsoft.com/kb/186133, a technique is mentioned that enables a developer to dynamically number rows in a SELECT Transact-SQL statement. This technique is handy for paginated display of data. 

To achieve the same functionality, typically, developers resort to techniques like copying data (or primary keys) to a temporary table with an identity column and then selecting data for the requested page from the temporary table (or joining it to the source table if only primary keys were copied). Both of these (and other) approaches are tremendously slower compared to the technique outlined in the article mentioned above.
As an example, consider the following query:

select row_number() over (order by a.au_id) as sequence, a.au_id, a.au_lname, a.au_fname, a.city
from pubs.dbo.authors a

sequence             au_id       city
-------------------- ----------- --------------------
1                    172-32-1176 Menlo Park
2                    213-46-8915 Oakland
3                    238-95-7766 Berkeley
4                    267-41-2394 San Jose
5                    274-80-9391 Oakland
6                    341-22-1782 Lawrence
7                    409-56-7008 Berkeley
8                    427-17-2319 Palo Alto
9                    472-27-2349 Covelo
10                   486-29-1786 San Francisco
11                   527-72-3246 Nashville
12                   648-92-1872 Corvallis
13                   672-71-3249 Walnut Creek
14                   712-45-1867 Ann Arbor
15                   722-51-5454 Gary
16                   724-08-9931 Oakland
17                   724-80-9391 Oakland
18                   756-30-7391 Oakland
19                   807-91-6654 Rockville
20                   846-92-7186 Palo Alto
21                   893-72-1158 Vacaville
22                   899-46-2035 Salt Lake City
23                   998-72-3567 Salt Lake City

(23 row(s) affected)

As you can see, there is now a dynamically generated sequence in the result set. The best thing is that this sequence number is generated by sorting on a specific column (or a set thereof) and, so, any given row is guaranteed to always have the same sequence number provided that it’s sorted on a primary key (typically a numeric, auto-incrementing one, though, any primary key incrementing in a natural sort order would work).

Now imagine you want to paginate over this result set. To make the example simple, let’s just say that you want to select rows 5 through 10 (in a real world application, you’d calculate start and end sequence numbers based on the following information: total number of pages in result set, currently requested page, and rows per page). Here’s how you’d do that:

select *
from (
    select row_number() over (order by a.au_id) as sequence, a.au_id, a.city
    from pubs.dbo.authors a
) as ResultSet
where sequence >= 5 and sequence <= 10

sequence             au_id       city
-------------------- ----------- --------------------
5                    274-80-9391 Oakland
6                    341-22-1782 Lawrence
7                    409-56-7008 Berkeley
8                    427-17-2319 Palo Alto
9                    472-27-2349 Covelo
10                   486-29-1786 San Francisco

(6 row(s) affected)

As these examples demonstrate, with 2005 and later versions of SQL Server, there is no need to use temporary tables or complex cursors for paginating through large sets of data.

Happy coding.

Friday, September 10, 2010

Free Transfer of Personal Documents to Kindle

If you've a 3G only Kindle (Kindle DX, for example) and you'd like to transfer your personal documents to your Kindle without incurring the associated fee, you can send attachments to "name"@free.kindle.com (notice that it's FREE.kindle.com vs. kindle.com) to be converted and e-mailed to your computer at the e-mail address associated with your Amazon.com account log-in. You can then transfer the document to your Kindle using your USB connection.

For example, if your Kindle email address is jdoe@kindle.com, send your attachments to jdoe@free.kindle.com.

Happy saving money!

Friday, July 23, 2010

Minimizing Skype and Windows Live Messenger to Notification Area

Windows 7 is a digital blessing and even more so as Windows Vista proved to be such a pain in the neck. However, like most things in life, Windows 7 is also not perfect. One of the issues (some might say it's a feature) is that certain programs, which typically would run minimized in the Notification Area, like the Taskbar so much that they always remain there while running. Two such programs are Skype and Windows Live Messenger.

Luckily, forcing these programs to stay where they belong -- the Notification Area -- is easy. Follow the following two links for two great short tutorials that show exactly how to achieve that:-

1. How to Minimize Skype to Windows 7 Notification Area
2. How to Minimize Windows Live Messenger to Windows 7 Notification Area

I hope you'll enjoy the extra, valuable Taskbar space after you send these two sticky programs to the Notification Area!

Tuesday, February 16, 2010

Murphy's Laws of Programming

Here are some of Murphy's laws of programming that I am producing from an excellent software architecture book -- Microsoft .NET: Architecting Applications for the Enterprise. Read and have fun!
  • Real programmers don't comment their code. If it was hard to write, it should be hard to understand.
  • Ninety percent of a programmer's errors come from data from other programmers.
  • Walking on water and developing software to specification are easy as long as both are frozen.
Happy architecting software!

Sunday, November 15, 2009

ACM Membership Benefits

I've been a member of ACM (http://www.acm.org) for about a year now and it's almost renewal time. It's been arguably the best investment I made last year! As a member of ACM, I am entitled to a number of great benefits that help me excel in my career. My favorite ACM benefits are online books from Safari and Books24x7 and Element K-based online courses and virtual labs. Here's a complete list of what you get with an ACM membership:

  • A full year 12-issue subscription to the newly redesigned and redefined "Communications of the ACM," ACM's flagship publication, the most trusted source for industry information for today's computing professionals.
    http://www.cacm.acm.org
  • Access to 2,500 online courses in multiple languages and 1,000 virtual labs.
    http://pd.acm.org
  • Access to 1,100 online books on today's hottest IT topics including 600 selections from Safari® Books Online featuring leading publishers such as O'Reilly, and 500 titles from books24x7®.
    http://pd.acm.org
  • ACM Career & Job Center - Whether you are a seasoned professional, or a student studying computing, you will find valuable career resources and extensive job postings in the ACM Career & Job Center.
    http://campus.acm.org/careercenter
  • Full access to ACM's enormous bank of over two million bibliographic citations in the Online Guide to Computing Literature.
    http://www.acm.org/guide
  • Full access to the new acmqueue website featuring Planet Queue blogs, case studies, CTO Roundtables, video and audio content, and much more.
    http://queue.acm.org
  • The option to subscribe to the powerful ACM Digital Library with 50+ years of archives and more than 40 publications.
    http://www.acm.org/dl
  • The opportunity to become a mentor through ACM's partnership with MentorNet, the leading organization promoting e-mentoring relationships between students and professionals in the areas of engineering and science.
    http://www.acm.org/mentornet
  • ACM online publications that keep you current on the latest computing developments:-
    • "TechNews" and "CareerNews" digests for professional and career trends
    • "MemberNet" brings you the world of ACM…and beyond

    http://www.acm.org/publications

It's important to note that all members must subscribe to the purposes of ACM. To access the ACM Code of Ethics go to: http://www.acm.org/about/code-of-ethics.