Re: why use final here
Ravi wrote On 04/11/07 16:35,:
class MouseEvents {
public static void main(String args[]) {
final Frame mainWindow = new Frame("Main Window");
Button btnClr = new Button("Clear");
btnClr.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent
me) {
mainWindow.repaint();
}
} );
mainWindow.setSize(200,200);
mainWindow.setLayout(new FlowLayout());
mainWindow.add(btnClr);
mainWindow.setVisible (true);
mainWindow.addMouseListener(new
MyMouseAdapter(mainWindow));
}
}
class MyMouseAdapter extends MouseAdapter {
Frame FListener;
MyMouseAdapter(Frame FListener) {
this.FListener = FListener;
}
public void mouseClicked(MouseEvent me) {
FListener.getGraphics().drawString("*",me.getX(),me.getY());
}
}
The problem is that use of mainWindow (as used for the mouseClick
event of the btnClr) requires mainWindow to be final because *too*
much nesting. Why? Couldn't get it.
Because the MouseAdapter object that listens for events
on btnClr may (almost certainly will) live on after the
main() method returns. When main() returns, all its local
variables -- including mainWindow -- cease to exist, and
yet the MouseAdapter instance still needs the value. How
can the long-lived MouseAdapter use a variable that has
already disappeared?
Java solves the problem with some behind-the-scenes
magic. What actually happens is that the new MouseAdapter
inner class is defined with an extra instance variable of
type Frame and with an "invisible" name invented by the
compiler. When the inner-class object is constructed, this
invisible variable is initialized with the current value of
main()'s mainWindow variable, and all the object's uses of
mainWindow are silently rewritten to use the invisible
variable instead. You write `mainWindow.repaint()', but
javac changes it to `hidden_synthetic_variable.repaint()'
(that isn't the actual name, of course). Since the hidden
synthetic variable refers to the same Frame mainWindow does,
you repaint the desired Frame.
But what would happen if main() went on to change the
value of mainWindow, after constructing the MouseAdapter?
Then mainWindow and hidden_synthetic_variable would not
agree; they would point to different Frames and you would
probably be surprised when the "wrong" Frame repainted.
Java's designers might have chosen to allow this and let
you be surprised, but instead they decided to require that
mainWindow be final and hence unchangeable: That way, it
can never disagree with hidden_synthetic_variable. Since
you cannot change mainWindow, you cannot be unpleasantly
surprised when changing it fails to affect the already-
constructed MouseAdapter instance.
--
Eric.Sosman@sun.com