Java静态类变量

时间:2016-07-27 01:15:29

标签: java class static

我正在努力弄清楚为什么以下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

5 个答案:

答案 0 :(得分:4)

有不同的方面发挥作用。

默认值

Java中的变量具有默认值,即使您未指定它们也是如此。对于int,这是0,因此App类的初始值为:

int ns = 0;
static int s = 0;

所以实际上ns不是“为ref3设置为0”,而是保持其初始值,而ref1ref2显式改变了值。

变量范围

让我们看一下App的构造函数:

App (int ns) {
  if (s < ns) {
    s = ns;
    this.ns = ns;
  }
}

有两个名称为ns的不同变量:

  • this.ns,引用实例级别的字段(此时仍具有初始值0
  • ns(不含this),仅在构造函数中可见,并且具有通过构造函数参数(50125或{{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)

nss < ns

时设置

ref1您传递ns = 50,但s未初始化且java假定s为零,因此输入if ( s < ns )并设置ref1的类变量ns以及静态ns50

ref2您传递ns = 125s为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初始化为0(默认为int)
  • 0&lt;因此50设置为50
  • 50&lt;因此125将两者都设置为125
  • 125&gt;因此,如果分支,则不执行100。 ns在构造函数的末尾未初始化,因此默认情况下它被初始化为0

此外,您在该步骤之后打印值,因此我们的唯一s绑定到125

答案 4 :(得分:0)

s的值每次达到125,因为它是静态变量,并且静态变量对于类是通用的,因此它们的值不会因您创建的每个对象而更改。在所有对象创建之后调用doPrint方法,因此s的最近值 125 ,每次调用doPrint方法的输出也是如此。

nsref3的构造函数中,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>