Java - 构造函数如何知道其参数/参数(?)何时更改

时间:2013-08-21 00:54:29

标签: java methods constructor

我有两个类:Base和Starter。这是Base中的代码:

String contestantName;

public Base (String contestantName) {
    this.contestantName = contestantName;
}

public void setName() {
    contestantName = "Tony";
}

public void returnName() {
    System.out.println(contestantName);
}

这是Starter中的代码:

    public static void main(String[] args) {

    Base tester = new Base(null);

    tester.returnName();

    tester.setName();

    tester.returnName();

}

我想知道是否有人可以向我解释这里的事件顺序。我已声明变量contestantName并在Base()的语句体中调用它。当我创建tester时,它的contestantName开始为null。在为contestantName重新分配tester为“Tony”之后,测试人员的构造函数何时“知道”它的参赛者名称已更改?是否与隐式调用和显式调用有关(即我显式调用setName()然后JVM / Java在重新赋值后隐式调用String contestantName)?

另外,我是否要求这些揭示某些我缺乏的主题或信息,如果是这样,它是什么,我在哪里可以学到它?也有点偏离主题,但是我使用的命名法是正确的吗?

6 个答案:

答案 0 :(得分:1)

调用方法后,它“知道”它的名字是Tony。如果你从来没有调用过这个方法,它就永远都不会知道它被称为“null”(我觉得这很难过。)看看它是如何从构造函数中以任何方式实际调用的,它只会“知道”它所设置的它为null。然后它将在没有构造函数接收任何更新的情况下进行更改。

您还应该将returnName()方法设置为类似以下内容的

public String returnName(){
   return contestantName;
}

所以它返回你要打印的值,因为这似乎就是你所追求的(然后打印你的main方法返回的字符串。)

答案 1 :(得分:0)

构造函数真的不应该知道值何时发生了变化。构造函数可以简化为仅仅是创建新对象的方法。一旦该方法执行了程序员给出的所有指示,就完成了。然后应该设置对象。因此,当您使用setName()时,Base对象已更改其值。但是,到那时,构造函数对该对象不再有任何影响。

答案 2 :(得分:0)

事件序列字面上代码Starter

我认为你需要区分什么是代码和什么是内存。所有Java对象都是与一些行为(代码)绑定的一堆内存。

构造函数是一组有关如何设置对象的说明。它不“知道”任何东西 - 它在构造一个对象时只运行一次,并且在该对象的生命周期中再也不运行(一堆内存与Base的代码相关联)。

所以事件的确切顺序是:

  • JVM加载并验证类Base
  • Base tester表示“保留足够的内存字节以引用Base的实例,该名称将引用tester
  • new Base()表示
    • 将执行转移到Base的构造函数
      • 将执行转移到java.lang.Object的构造函数,因为Base(自动)扩展Object,除非你说它扩展了其他内容
      • 初始化属于Base
      • 的所有字段
      • 运行Base构造函数中的代码,该构造函数将参数contestantName分配给实例变量contestantName
        • 字面意思,这意味着“将contestantName参数指向的字符串的内存地址复制到实例变量contestantName

当您调用setName()并更改实例变量contestantName的值时,这与构造函数无关 - 构造函数只是在Base时运行的一些内容对象已创建。

答案 3 :(得分:0)

首先,对象Base创建为空contestantName,分配给null。在new Base(null)之后,contestantName再次分配给null。然后打印contestantName。输出为null。然后在致电setName contestantName后,将Tony分配给Tony。最后打印contestantName {{1}}的值。

答案 4 :(得分:0)

我不认为构造函数“知道”参赛者名称已经改变。构造函数只是将contestantName设置为您传递给它的任何内容。构造函数用于创建对象并修改对象的属性(例如contestantName),以便可以使用对象(例如,在main方法中)。以下是我认为发生的事情:

运行Java程序时,首先运行的是main方法。

在main方法中,使用

声明变量test
Base tester ...

您将测试人员(使用“Base tester =”)分配给

new Base(null)

调用Base类的构造函数并将其作为参数传递给null。在Base类中,您有一个字段contestantName,因为您声明了

String contestantName;

现在,我们执行你在Base类的构造函数中编写的任何内容。构造函数中的此语句执行:

this.contestantName = contestantName;

并且由于您传入null作为参数,因此this.contestantName设置为null。既然构造函数调用已经完成,那么就创建了对象,然后我们返回到main方法,在那里我们刚创建的新Base对象被分配给变量tester。该声明现已完成:

Base tester = new Base(null);

主方法中的下一个语句是

tester.returnName();

这会调用tester的returnName()函数。因此,returnName()方法中的语句

System.out.println(contestantName);

执行。由于contestantName已设置为null,因此null应该是您的计算机打印出来的内容。这个returnName()方法完成,我们返回main方法。主方法中的下一个语句是

tester.setName();

因此,我们执行setName()方法。在setName()方法中,有语句

contestantName = "Tony";

因此,tester对象中的字段matchName设置为“Tony” - 它不再为null。现在setName()方法完成,我们返回main方法。

主方法中的最后一句是

tester.returnName();

因此,我们在tester对象中执行returnName()方法。 returnName()方法具有语句

System.out.println(contestantName);

如果你还记得,contestantName已被设置为“Tony”,所以这一次,你的电脑应打印出“Tony”。现在returnName()方法已经完成,我们返回main方法。

主要方法到达终点,因此它结束,程序终止。

如果不清楚,请告诉我。

至于命名方法,returnName()函数可能应该重命名为printName()。毕竟,returnName()不返回任何内容(它的返回类型为void)。

答案 5 :(得分:0)

撰写setName()时,在contestantName方法中,您实际上正在访问this.contestantName。在该方法中,您可以使用两种符号,所以写:

public void setName() {
    contestantName = "Tony";
}

public void setName() {
    this.contestantName = "Tony";
}

完全一样。

在构造函数中,事情有点不同,你不能写:

public Base (String contestantName) {
    contestantName = contestantName;
}

因为参数contenstantName“隐藏”具有相同名称的字段,所以您基本上将参数分配给自身。在这种情况下,您可以像您一样放置前缀this.或更改参数名称以避免名称冲突,例如:

public Base (String cName) {
    contestantName = cName;
}

希望这有点澄清。

您应该阅读一些变量/字段范围教程,以更好地了解如何在Java中引用变量。