user476033
user476033

Reputation: 4727

When you call new in Java, does it create a copy of the constructor, or the class?

I am currently working on a Java assignment, and for some reason, it works - but to my mind, it shouldn't ! What I have is a main method, creating three new buttons with the call

panel.add(new ButtonApp());

ButtonApp is the constructor defined in my ButtonApp class.

At the beginning of my class, I have a variable declared as follows :

public int clicks = 0;

The purpose of this variable is to keep track of the amount of times the user clicks on their specific ButtonApp. clicks++ is called after every click.

Now, in my mind, every time you click the button, the clicks variable shoudl get incremented, and so, if you click the left button, it should increment the middle and right buttons also.

So essentially what I have, in quick short psuedocode, is :

public class ButtonApp() {
    public int clicks =0;

    public static void main(String[] args) {
        //create JPanel/Frame etc etc
        panel.add(new ButtonApp());
        panel.add(new ButtonApp());
        panel.add(new ButtonApp());
    }

    public ButtonApp(){
        //creates a new button
        this.actionListener(this);
    }

    public void update(){
        clicks++;
    }

    public void actionPerformed (ActionEvent event){
        update();
    }
}

Am I not always incrementing one clicks variable here ?

Upvotes: 2

Views: 292

Answers (6)

Jigar Joshi
Jigar Joshi

Reputation: 240908

There will be 3 click variable for 3 different object of ButtonApp you have created by

panel.add(new ButtonApp());
panel.add(new ButtonApp());
panel.add(new ButtonApp());

if you want to count total clicks , ignoring which button clicks just make click variable static

Currently with each object a different click variable is there, but if you make it static it would be same per class loaded

Also See

Upvotes: 3

Sean Patrick Floyd
Sean Patrick Floyd

Reputation: 298978

Am I not always incrementing one clicks variable here ?

No, you are dealing with instance variables. There is one copy of this variable per object created with new

If you changed the code to this:

public static int clicks =0;

You would indeed only have one variable that would be changed multiple times (static fields belong to the class, instance fields belong to the instance)

Reference:

(All from the Java Tutorial > Learning the Java Language > Classes and Objects section)

Upvotes: 8

Brian Agnew
Brian Agnew

Reputation: 272307

panel.add(new ButtonApp());

will create a new instance of your ButtonApp class, by calling your zero-arg/default constructor.

For each new instance, you'll have a new set of members, inclding clicks, and consequently that will be zero each time. Your code is not duplicated, but you will have different instances of this class, with their own set of data.

Upvotes: 0

Andrea Spadaccini
Andrea Spadaccini

Reputation: 12651

You create three instances of your ButtonApp class, so you increment the three attributes separately.

You might be confused because you embedded the main method in the same class, and you think that you are incrementing the clicks attribute of the instance related to main().

Keep in mind that main is static, and that means that there is no instance of your class related to main. Try to access clicks from main and you'll see an error.

Upvotes: 1

erickson
erickson

Reputation: 269717

Every ButtonApp has its own clicks variable. If you have three buttons, you have three clicks, and a given click is only incremented when its button is pressed.

If you want one click variable, you could make it a class variable, instead of an instance variable. This is done with the static keyword:

private static int clicks = 0;

In general, though, it's better to avoid static members. A more complex, but flexible, approach would be to share a counter object among all buttons that you want to link. You could create your own, but AtomicInteger is a natural fit, and provides thread safety if you will be accessing this state from outside the UI thread.

class ButtonApp {

  private final AtomicInteger clicks;

  ButtonApp(AtomicInteger clicks) { this.clicks = clicks; }

  void update() {
    clicks.incrementAndGet();
  }

  ...

}

Upvotes: 2

Jim Garrison
Jim Garrison

Reputation: 86774

new() creates an instance of the class' DATA -- i.e. any member variables. Code is not duplicated. In your case, each class has its own 'clicks' member variable.

If you had declared clicks to be static, then it would be a "class variable", belonging to the class itself and not its instances, and then there would be only a single copy. However, you did not declare it static, so each instance (i.e. each "thing" that was created by new()) gets its own copy.

Upvotes: 5

Related Questions