You haven't proven that there are two instances of B. You can do this by
printing out System.identityHashCode(this) from inside updateUI().
Two questions:
1. Regarding the following code, why is updateUI called twice?
ie, once implicitly by B's constructor at line 8 and once explicitly
at line 9.
2. Why is a second instance of Object B created? That's the only
explanation that makes sense given alreadyUpdatedUI's behavior.
ie, if this flag is declared to be static at line 5 then the second
call to updateUI shows that alreadyUpdatedUI is true and, hence,
only one dumpStack gets printed. Note also that it doesn't matter
if updateUI is declared synchronized or not.
Thank you,
import javax.swing.*;
class B extends JButton
{
boolean alreadyUpdatedUI = false; // line 5
public B ()
{ // line 8
updateUI (); // line 9
}
public void updateUI ()
{
System.out.println ("alreadyUpdateUI: " + alreadyUpdatedUI);
if (alreadyUpdatedUI)
return;
alreadyUpdatedUI = true;
Thread.currentThread ().dumpStack ();
}
}
public class A
{
public static void main (String args[])
{
B newB = new B ();
}
}
% java A
alreadyUpdateUI: false
java.lang.Exception: Stack trace
at java.lang.Thread.dumpStack(Thread.java:1071)
at B.updateUI(A.java:18)
at javax.swing.AbstractButton.init(AbstractButton.java:1930)
at javax.swing.JButton.<init>(JButton.java:109)
at javax.swing.JButton.<init>(JButton.java:64)
at B.<init>(A.java:8)
at A.main(A.java:26)
alreadyUpdateUI: false
java.lang.Exception: Stack trace
at java.lang.Thread.dumpStack(Thread.java:1071)
at B.updateUI(A.java:18)
at B.<init>(A.java:9)
at A.main(A.java:26)
% java -version
java version "1.4.1_02"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.1_02-b06)
Java HotSpot(TM) Client VM (build 1.4.1_02-b06, mixed mode)
% uname -a
SunOS sunbox 5.8 Generic_117000-03 sun4u sparc SUNW,Sun-Blade-100