One of the most misinterpreted structures in Java is the inner class. The inner class looks like this.
java
class A{
class B{}
}
But what exactly does this do? It looks like just two classes. But, inner classes cannot be instantiated regularly. By this, I mean you cannot type new A.B(); //yes, you must refer to it as A.B . This displays the compiler error: “an enclosing instance that contains A.B is required.” If you’re like me and can’t make any sense of error messages, this is basically saying ”You must have an object of type A to have an object of type B.” Think of the inner class as an attribute. Once you understand this, the rest of inner classes will be a piece of cake.
Section 1: Basics of the Inner Class
Inner classes have mystical powers. You can access attributes or methods of the outer class in the inner class. I could type this.
java
class A{
int x=3;
class B{
public void displayInt(){
System.out.print(x);
}
}
}
This would print 3 if the displayInt method was called.
In fact, I could even do this.
java
class A{
private int x=3;
class B{
public void displayInt(){
System.out.print(x);
}
}
}
Even though the attribute is private, I can STILL use the inner class to read it.
Section 2: Actually Using the Inner Class
How do we instantiate an inner class? As I said above, you need an object of the outer class, first. I could create an object of type B with these lines of code.
java
object1 = new A();
A.B object2 = object1.new B();
I use the dot operator to create an inner class instance WITHIN the instance of the outer class. Now that we’ve instantiated it, we can run object2.displayInt();.
CODE
3
Just as we expected.
But say we had a class (call it C), and we created an inner class within it (call it D), and we want to access the object of type C using its inner object of type D. In other words, we are using the inner object to get the outer object. We do this by typing in C.this somewhere within a method of the inner class. C.this will be the “OUTER this”.
Section 3: Putting a Class Inside of a Method
java
class E{
public void doStuff(){
class F{}
}
}
I know what you’re thinking now. “Now he’s getting overboard. I thought putting classes inside of packages was bad enough. Now we’re putting classes inside of classes, and even classes instead of methods. What madness is this?” Don’t worry. Known as method-local inner classes, these work just as regular inner classes do but they’re local to the method. So you can’t try to instantiate an object of a method-local inner class unless you’re instantiating it INSIDE the method and AFTER the inner class is defined. Another drawback is that you can’t access local variables within a method-local inner class
Section 4: A Class without a Name
Consider this snippet of code.
java
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent event){
System.exit(0);
}
});
This looks daunting. We have a code block immediately following a constructor. We also have a strange }); at the end. It’s actually not that bad- when we put a code block next to a constructor, we’re actually just creating another class. This class does not have any name, so it’s called an anonymous class. What we’re doing here is creating a new anonymous subclass of WindowAdapter. Then, within the code block, we’re overriding the windowClosing method. Then, we’re instantiating the class. That’s all an anonymous inner class does- subclasses, overrides, and instantiates.
Now, consider this snippet of code.
java
new Thread(new Runnable(){
public void run(){
System.out.print(“Running”);
}
}).start();
If you understood the last paragraph about anonymous inner classes, you shouldn’t have any trouble understanding this code. (except the thread logic, maybe, but that isn’t important here) The most confusing thing about this is the new Runnable() . We usually can’t instantiate an interface. However, this works exactly the same way as the regular anonymous inner class. Instead of subclassing Runnable, however, the code automatically implements it.
Section 5: Modifying an Inner Class
Remember modifiers? You know, the things you tag onto variables, like public and abstract? You can also put them on inner classes. Here’s a summary of what the various modifiers do
• Abstract- makes the class able to have abstract methods
• Final- makes the class unsubclassable (Yes, I made up that word)
• Public- makes the class able to be accessed ANYWHERE
• Private- the class cannot be accessed except within the outer class or the inner class itself.
• Protected- the class can be accessed by any other class of the same package, or by subclasses, through inheritance
• Static- turns the inner class into just a regular old class. The only difference is that you use the dot operator to refer to a static inner class, but you don’t use it to refer to a regular class.
• Strictfp- strict floating point operations