■ Named inner classes occur within another class.
■ An inner class can extend any other class or interface. Except it can't extend its own enclosing class.
■ Class Inner1 below demonstrates a named inner class with one method, used to provide an event handler:
. . . .
Button
button1 = new Button( "Press me" );
Inner1
in = new Inner1( );
button1.addActionListener(
in );
}
// end of some method beginning way up above
class
Inner1 implements java.awt.event.ActionListener {
public void actionPerformed( ActionEvent
event) {
Object obj =
event.getSource( );
if ( obj ==
button1 ) /* then do something */ ; }
} // end of Inner1 class
} // end of the larger enclosing outer class beginning way up above
■ An inner class can be private or static. See static inner classes below.
■ Each inner class results in the generation of a separate file with a filename like Outside$Inside.class.
■ Named inner classes cannot repeat their enclosing classname.
■ Named inner classes can access everything in
their enclosing class, including all the private variables, and
also the enclosing class's static and instance members.
i.e.
■ Here's how to reference the outer instance (named Outside below) from inside the inner class:
Outside out = Outside.this; then you can say out.variablename
It can be put
more simply in one statement as Outside.this.variablename
■ To create and use a regular (meaning non-static) inner class, the code is:
Outside
o = new Outside( ); followed
by Outside.Inside i =
o.new Inside( );
A shorter
alternative to the above code is: Outside.Inside i = new Outside( ).new
Inside( );
■ static inner classes can only refer to static members directly. No instance variables are accessible from a static inner class.
■ You can instantiate a static inner class without creating an instance of the outer class first. i.e.
OutsideClass.InsideClass
i = new OutsideClass.InsideClass( );
■ Class InsideStatic below is a static inner class demonstrating its static-only accesses:
class Outside {
String h = "Hello ";
static String w = "World";
static class InsideStatic {
void innermethod( ) {
// System.out.println( h ); //
the compiler will reject this reference to a non-static
// System.out.println( Outside.h
); // the compiler will
reject this reference to a non-static
System.out.println( w ); // however
accessing static w is allowed
System.out.println( Outside.w ); // this form of reference
also works
}
}
public static void main(String[ ] args) {
Outside.InsideStatic i = new
Outside.InsideStatic( );
i.innermethod( );
}
}
■ Local inner classes are named and appear within a method or code block.
■ Local inner classes can access the following things:
(1) The enclosing method’s final variables
(2) The enclosing
method’s final
parameters
(3) All static and instance members of the larger enclosing class itself, whether final or private or not.
■ Class Inner2 below is a local named inner class demonstrating its access to outside variables:
public class Outer {
private static final int F1 = 1;
private String F2 = "2";
Outer( ) {
amethod( 3 );
}
public void amethod( final int F3 ) {
final int F4 = 4;
class Inner2 {
void doSomething( ) {
System.out.println( "F1
is " + F1 ); // access to
static members of the enclosing class
System.out.println( "F2
is " + F2 ); // access to
non-static or private members also
System.out.println( "F3
is " + F3 ); // access to
final parametes of the enclosing method
System.out.println( "F4 is
" + F4 ); // access to
final members of the enclosing method
}
}
new Inner2( ).doSomething( );
}
public static void main(String[ ] args) {
Outer O = new Outer( );
}
}
■ Local inner classes classes cannot be accessed by code located outside their enclosing code block or method. i.e.
■ Objects created by local inner classes can
still reference their final
variables after the actual inner class code block or method ends. i.e.
■ Anonymous inner classes have no name
and no constructor.
■ Anonymous inner classes are declared within methods, usually as part of a method call, created with just a new. They are commonly found in code for handling AWT events. Below is an example of an anonymous inner class supplying an event handler for an AWT component named button1:
button1.addActionListener(
new ActionListener( ) {
public
void actionPerformed( ActionEvent aevent ) {
/* do something */
}
}
)
;
■ Things which anonymous inner classes can access are the same as as local inner classes.
(1) The enclosing method’s final variables
(2) The enclosing
method’s final
parameters
(3) All static and instance members of the larger enclosing class itself, whether final or private or not.
■ The anonymous inner class below demonstrates access to various variables:
public class Outer2 {
private static final int V1 = 1;
private String V2 = "2";
Outer2( final int V3 ) {
final int V4 = 4;
amethod(new Object( ) {
public String toString( ) {
System.out.println( "V1 is
" + V1 ); // access to
final members of the enclosing class
System.out.println( "V2
is " + V2 ); // access to
its non-final private members
System.out.println( "V3
is " + V3 ); // access to
final parametes of the enclosing method
System.out.println( "V4
is " + V4 ); // access to
final members of the enclosing method
return "OK";
}
} // end anonymous inner class
);
} // end constructor
void amethod( Object o ) {
o.toString( );
return;
}
public static void main(String[ ] args) {
final int V = 3;
Outer2 O = new Outer2( V );
}
}
// end Outer2
■ Although they have no name, anonymous inner
classes can begin with new. i.e.
AnActualInterfaceName( ) {...}
or
new AnActualClassName( ) {....}
■ If an actual interface name is used, normal rules apply for supplying all of the interface's methods.
Anonymous inner classes can explicitly extend a class or implement an interface, if desired. However it's done for them automatically
with the new.
■ You cannot refer to an anonymous inner class with an object
reference handle, since they have no creation statement creating such a handle.
■ Anonymous inner classes are automatically
named and numbered, in sequence, as Enclosing$1.class, Enclosing$2.class, etc.