Question

I have develop sample project as a proof concept of class variable (static). But when i run two instance of the StaticCounter.java class, The shared variable (static) will give to the two instance different reference?!!.

Static Variable Documentation:

  • Class Variables (Static Fields) A class variable is any field declared with the static modifier; this tells the compiler that there is exactly one copy of this variable in existence, regardless of how many times the class has been instantiated. A field defining the number of gears for a particular kind of bicycle could be marked as static since conceptually the same number of gears will apply to all instances. The code static int numGears = 6; would create such a static field. Additionally, the keyword final could be added to indicate that the number of gears will never change.

The Code of StaticCounter.java:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class StaticCounter extends JFrame {

public static int COUNTER = 0;
private JButton btnCounter;
private JButton btnShowValue;
private JLabel lblCounter;

public StaticCounter() {
    initComponents();
}

private void initComponents() {

    btnShowValue = new JButton();
    btnCounter = new JButton();
    lblCounter = new JLabel();

    setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

    btnShowValue.setText("Show Value");
    btnShowValue.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent evt) {
            showValue(evt);
        }
    });

    btnCounter.setText("Counter +1");
    btnCounter.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent evt) {
            doCount(evt);
        }
    });

    lblCounter.setFont(new Font("Tahoma", 1, 36)); 
    lblCounter.setText("0");

     GroupLayout layout = new GroupLayout(getContentPane());
    getContentPane().setLayout(layout);
    layout.setHorizontalGroup(
            layout.createParallelGroup( GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
            .addContainerGap()
            .addGroup(layout.createParallelGroup( GroupLayout.Alignment.LEADING)
            .addGroup( GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
            .addGap(0, 0, Short.MAX_VALUE)
            .addComponent(btnCounter)
            .addPreferredGap( LayoutStyle.ComponentPlacement.RELATED)
            .addComponent(btnShowValue))
            .addComponent(lblCounter,  GroupLayout.DEFAULT_SIZE,  GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
            .addContainerGap()));
    layout.setVerticalGroup(
            layout.createParallelGroup( GroupLayout.Alignment.LEADING)
            .addGroup( GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
            .addContainerGap()
            .addComponent(lblCounter,  GroupLayout.DEFAULT_SIZE, 55, Short.MAX_VALUE)
            .addPreferredGap( LayoutStyle.ComponentPlacement.RELATED)
            .addGroup(layout.createParallelGroup( GroupLayout.Alignment.BASELINE)
            .addComponent(btnShowValue)
            .addComponent(btnCounter))
            .addContainerGap()));

    pack();
}                 

private void doCount( ActionEvent evt) {
    ++StaticCounter.COUNTER;
    lblCounter.setText(String.valueOf(StaticCounter.COUNTER));
}

private void showValue( ActionEvent evt) {
    JOptionPane.showMessageDialog(null, String.valueOf(StaticCounter.COUNTER));
}

public static void main(String args[]) {

    EventQueue.invokeLater(new Runnable() {
        @Override
        public void run() {
            new StaticCounter().setVisible(true);
        }
    });
}
}

Now if you run it twice or thrice, the static will be instance variable not class variable? but if I change the initialize in the main twice or thrice in one run of the class it works fine?

public static void main(String args[]) {

    EventQueue.invokeLater(new Runnable() {
        @Override
        public void run() {
            new StaticCounter().setVisible(true);
            new StaticCounter().setVisible(true);
        }
    });
}
}

So, Why?!

Was it helpful?

Solution

In this example

@Override
public void run() {
    new StaticCounter().setVisible(true);
}

There's not much to see since you only have one StaticCounter object. When you click the Counter++ button, the value goes up. Good 'till here?

In this one

@Override
public void run() {
    new StaticCounter().setVisible(true);
    new StaticCounter().setVisible(true);
}

It's more easy to see static behavior. When you click one of the JFrame's Counter++ button, you see the value go up. Obviously it won't change the other window because you haven't redrawn it, but if you click the other's button, you will see that the next value continues from where the static counter was. This proves that there is only one instance of the counter in the JVM.

OTHER TIPS

The static variable DOES WORK in your code. If you click on button in one frame and display it in another, it shows the correct incremented values. If you wish to automatically update UI, it's completely different thing, this has nothing to do with static or not static.

If you are in doubt, just add logging in in the method doCount(). Then you will see that the counter changes correctly, ant that this is the same caounter for all frames. So there is no problem with static.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top