我有两个类: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)?
另外,我是否要求这些揭示某些我缺乏的主题或信息,如果是这样,它是什么,我在哪里可以学到它?也有点偏离主题,但是我使用的命名法是正确的吗?
答案 0 :(得分:1)
调用方法后,它“知道”它的名字是Tony。如果你从来没有调用过这个方法,它就永远都不会知道它被称为“null”(我觉得这很难过。)看看它是如何从构造函数中以任何方式实际调用的,它只会“知道”它所设置的它为null。然后它将在没有构造函数接收任何更新的情况下进行更改。
您还应该将returnName()方法设置为类似以下内容的
public String returnName(){
return contestantName;
}
所以它返回你要打印的值,因为这似乎就是你所追求的(然后打印你的main方法返回的字符串。)
答案 1 :(得分:0)
构造函数真的不应该知道值何时发生了变化。构造函数可以简化为仅仅是创建新对象的方法。一旦该方法执行了程序员给出的所有指示,就完成了。然后应该设置对象。因此,当您使用setName()时,Base对象已更改其值。但是,到那时,构造函数对该对象不再有任何影响。
答案 2 :(得分:0)
事件序列字面上代码Starter
。
我认为你需要区分什么是代码和什么是内存。所有Java对象都是与一些行为(代码)绑定的一堆内存。
构造函数是一组有关如何设置对象的说明。它不“知道”任何东西 - 它在构造一个对象时只运行一次,并且在该对象的生命周期中再也不运行(一堆内存与Base的代码相关联)。
所以事件的确切顺序是:
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方法中,使用
声明变量testBase 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中引用变量。