Когда вы вызываете new в Java, он создает копию конструктора или класса? - PullRequest
2 голосов
/ 03 февраля 2011

В настоящее время я работаю над заданием на Java, и по какой-то причине оно работает - но, на мой взгляд, не должно! У меня есть основной метод создания трех новых кнопок с вызовом

panel.add(new ButtonApp());

ButtonApp - это конструктор, определенный в моем классе ButtonApp.

В начале моего класса у меня была переменная, объявленная следующим образом:

public int clicks = 0;

Цель этой переменной - отслеживать, сколько раз пользователь нажимал на свое конкретное ButtonApp. clickks ++ вызывается после каждого клика.

Теперь, на мой взгляд, каждый раз, когда вы нажимаете кнопку, переменная кликов должна увеличиваться, и поэтому, если вы нажмете левую кнопку, она также должна увеличить среднюю и правую кнопки.

Итак, по сути, я имею в виду короткий короткий псевдокод:

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();
    }
}

Разве я не всегда увеличиваю здесь одну clicks переменную?

Ответы [ 6 ]

8 голосов
/ 03 февраля 2011

Разве я здесь не всегда увеличиваю переменную в один клик?

Нет, вы имеете дело с переменными экземпляра. Существует одна копия этой переменной для каждого объекта, созданного с new

Если вы изменили код на это:

public static int clicks =0;

У вас действительно будет только одна переменная, которая будет изменяться несколько раз (статические поля принадлежат классу, поля экземпляра принадлежат экземпляру)

Справка:

(Все из Учебное пособие по Java> Изучение языка Java> Классы и объекты раздел)

5 голосов
/ 03 февраля 2011

new () создает экземпляр класса DATA - то есть любые переменные-члены. Код не дублируется. В вашем случае каждый класс имеет свою собственную переменную-член "clickks".

Если бы вы объявили clicks как static, то это была бы «переменная класса», принадлежащая самому классу, а не его экземплярам, ​​и тогда была бы только одна копия. Однако вы не объявили его статическим, поэтому каждый экземпляр (т. Е. Каждая «вещь», созданная new ()) получает свою собственную копию.

3 голосов
/ 03 февраля 2011

Будет 3 переменная щелчка для 3 разных объектов ButtonApp, созданных вами

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

если вы хотите посчитать общее количество кликов, игнорируя, какие нажатия кнопки просто делают click переменным static

В настоящее время для каждого объекта существует отдельная переменная click, но если вы сделаете ее статической, она будет одинаковой для каждого загруженного класса

См. Также

2 голосов
/ 03 февраля 2011

Каждый ButtonApp имеет собственную переменную clicks.Если у вас есть три кнопки, у вас есть три clicks, и заданная click увеличивается только при нажатии ее кнопки.

Если вы хотите одну click переменную, вы можете сделать ее переменной классавместо переменной экземпляра.Это делается с помощью ключевого слова static:

private static int clicks = 0;

В общем, лучше избегать статических членов.Более сложным, но гибким подходом было бы разделение объекта счетчика между всеми кнопками, которые вы хотите связать.Вы можете создать свой собственный, но AtomicInteger является естественным соответствием и обеспечивает безопасность потока, если вы будете получать доступ к этому состоянию извне потока пользовательского интерфейса.

class ButtonApp {

  private final AtomicInteger clicks;

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

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

  ...

}
1 голос
/ 03 февраля 2011

Вы создаете три экземпляра вашего ButtonApp класса, поэтому вы увеличиваете три атрибута отдельно.

Вы можете быть озадачены тем, что встроили метод main в тот же класс и думаете, что увеличиваете атрибут clicks экземпляра, связанного с main().

Имейте в виду, что main - это static, и это означает, что нет ни одного экземпляра вашего класса, связанного с main. Попробуйте получить доступ к clicks из main, и вы увидите ошибку.

0 голосов
/ 03 февраля 2011
panel.add(new ButtonApp());

создаст новый экземпляр вашего ButtonApp класса, вызвав конструктор zero-arg / default.

Для каждого нового экземпляра у вас будет новый набор членов, включая clicks, и, следовательно, каждый раз он будет равен нулю. Ваш код не дублируется, но у вас будет различных экземпляров этого класса с собственным набором данных.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...