我正在努力弄清楚为什么以下Java代码具有以下输出。
具体来说,为什么s的值每次都设置为125,并且对于ref3,ns的值设置为0?
代码
public class App {
int ns;
static int s;
App (int ns) {
if (s < ns) {
s = ns;
this.ns = ns;
}
}
void doPrint () {
System.out.println("ns = " + ns + ", s = " + s);
}
public static void main(String[] args) {
App ref1 = new App(50);
App ref2 = new App(125);
App ref3 = new App(100);
ref1.doPrint();
ref2.doPrint();
ref3.doPrint();
}
}
输出
ns = 50, s = 125
ns = 125, s = 125
ns = 0, s = 125
答案 0 :(得分:4)
有不同的方面发挥作用。
Java中的变量具有默认值,即使您未指定它们也是如此。对于int
,这是0
,因此App
类的初始值为:
int ns = 0;
static int s = 0;
所以实际上ns
不是“为ref3设置为0”,而是保持其初始值,而ref1
和ref2
显式改变了值。
让我们看一下App
的构造函数:
App (int ns) {
if (s < ns) {
s = ns;
this.ns = ns;
}
}
有两个名称为ns
的不同变量:
this.ns
,引用实例级别的字段(此时仍具有初始值0
)ns
(不含this
),仅在构造函数中可见,并且具有通过构造函数参数(50
,125
或{{1}提供的值})。 100
是一个静态变量,与s
类本身相关联,而不是与特定实例相关联。因此,只要一个实例更改其值(例如,因为构造函数中的App
),所有其他实例(实际上:整个程序)将看到更新的值。
构造函数中的逻辑基本上将50 < 125
设置为目前为止所有提供的s
值的最大值,在本例中为ns
。尝试将125
方法移到上面几行,看看这些值是如何变化的。
有关值如何演变的完整概述,您还可以添加一些“调试”语句:
doPrint()
这将输出:
System.out.println("App.s=" + App.s);
App ref1 = new App(50);
System.out.println("ref1.ns=" + ref1.ns + ", ref1.s=" + ref1.s + ", App.s=" + App.s);
App ref2 = new App(125);
System.out.println("ref2.ns=" + ref2.ns + ", ref2.s=" + ref2.s + ", App.s=" + App.s);
App ref3 = new App(100);
System.out.println("ref3.ns=" + ref3.ns + ", ref3.s=" + ref3.s + ", App.s=" + App.s);
您甚至可以在创建第一个实例之前看到App.s=0
ref1.ns=50, ref1.s=50, App.s=50
ref2.ns=125, ref2.s=125, App.s=125
ref3.ns=0, ref3.s=125, App.s=125
始终等于ref.s
并且App.s
已存在。
答案 1 :(得分:2)
ns
在s < ns
,
ref1
您传递ns
= 50
,但s
未初始化且java假定s
为零,因此输入if ( s < ns )
并设置ref1
的类变量ns
以及静态ns
到50
ref2
您传递ns
= 125
但s
为50,if( s < ns )
成立,因此输入if并更新静态变量{{1} }到125和s
的类变量ref2
到125
ns
您传递了ref3
= ns
,但100
已经s
,因此如果有条件,则不会输入125
ns
1}}保持未初始化,打印时其值为零。
答案 2 :(得分:0)
如您所知,当使用关键字“static”声明变量时,它称为“类变量”。所有实例共享变量的同一副本。
因此,当App.s
运行时,App ref2 = new App(125)
为s
。在125
中,App ref3 = new App(100)
为ns
,而不是100
,因此您的if分配不会执行,这意味着s (125)
保持在初始默认值{{ 1}}。
答案 3 :(得分:0)
Java中的静态粗略意味着变量在所有类实例(和类本身)之间共享。它在其他所有内容之前进行初始化,当您在一个实例中更新它时,它会反映在所有其他实例中。
您的程序执行如下:
此外,您在该步骤之后打印值,因此我们的唯一s绑定到125
答案 4 :(得分:0)
s
的值每次达到125,因为它是静态变量,并且静态变量对于类是通用的,因此它们的值不会因您创建的每个对象而更改。在所有对象创建之后调用doPrint
方法,因此s的最近值 125 ,每次调用doPrint
方法的输出也是如此。
在ns
和ref3
的构造函数中,s
的{{1}}值设置为0。当您创建引用变量ns
时这发生在构造函数中:
ref3
因此,当您致电 `App (int ns)
{
if (s < ns) /* s is 125 and ns is 100 so the if statement evaluates
to false and the assignments don't happen*/
{
s = ns; // this isn't performed
this.ns = ns; // even this isn't performed
}
}`
时,ref3.doPrint()
的值 0 且ns
125 ,您的输出也是如此。< / p>