在Java中调用new时,是否会创建构造函数或类的副本?

时间:2011-02-03 16:45:26

标签: java class object

我目前正致力于Java任务,出于某种原因,它可行 - 但在我看来,它不应该!我所拥有的是一个主要方法,通过调用

创建三个新按钮
panel.add(new ButtonApp());

ButtonApp是我的ButtonApp类中定义的构造函数。

在课程开始时,我有一个声明如下的变量:

public int clicks = 0;

此变量的目的是跟踪用户点击其特定ButtonApp的次数。点击++会在每次点击后调用。

现在,在我看来,每次点击按钮时,点击变量shoudl都会增加,因此,如果单击左键,它也会增加中间和右侧按钮。

基本上我所拥有的,在快速短的伪代码中,是:

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 个答案:

答案 0 :(得分:8)

  

我是不是总是在这里增加一个点击变量?

不,您正在处理实例变量。每个使用new

创建的对象都有一个此变量的副本

如果您将代码更改为:

public static int clicks =0;

您确实只有一个可以多次更改的变量(静态字段属于该类,实例字段属于该实例)

<强>参考:

(全部来自Java Tutorial > Learning the Java Language > Classes and Objects部分)

答案 1 :(得分:5)

new()创建类'DATA的实例 - 即任何成员变量。代码不重复。在您的情况下,每个类都有自己的“点击”成员变量。

如果您已将clicks声明为static,那么它将是一个“类变量”,属于类本身而不是其实例,然后只有一个副本。但是,您没有将其声明为静态,因此每个实例(即由new()创建的每个“事物”)都会获得自己的副本。

答案 2 :(得分:3)

对于您通过

创建的ButtonApp的3个不同对象,将有3个点击变量
panel.add(new ButtonApp());
panel.add(new ButtonApp());
panel.add(new ButtonApp());

如果您想计算总点击次数,忽略哪个按钮点击只需click变量static

目前每个对象都有一个不同的click变量,但是如果你将它设为静态,那么每个加载的类都是相同的

另见

答案 3 :(得分:2)

每个ButtonApp都有自己的clicks变量。如果您有三个按钮,则有三个clicks,并且只有按下按钮时,给定的click才会递增。

如果您想要一个click变量,可以将其变为类变量,而不是实例变量。这是通过static关键字完成的:

private static int clicks = 0;

一般而言,最好避免使用静态成员。更复杂但更灵活的方法是在要链接的所有按钮之间共享计数器对象。您可以创建自己的,AtomicInteger是一个自然的选择,如果您将从UI线程外部访问此状态,则提供线程安全。

class ButtonApp {

  private final AtomicInteger clicks;

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

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

  ...

}

答案 4 :(得分:1)

您创建了ButtonApp类的三个实例,因此您可以单独增加这三个属性。

您可能会感到困惑,因为您将main方法嵌入到同一个类中,并且您认为您正在递增与clicks相关的实例的main()属性。

请注意,mainstatic,这意味着您的班级没有与main相关的实例。尝试从clicks访问main,您会看到错误。

答案 5 :(得分:0)

panel.add(new ButtonApp());

将通过调用零-arg / default构造函数来创建ButtonApp类的新实例

对于每个新实例,您将拥有一组新成员,包含clicks,因此每次都为零。您的代码不会重复,但您将拥有此类的不同实例,并拥有自己的数据集。