问题：静态变量必须初始化吗

最好初始化，如果不初始化的话，系统会像初始化全局变量一样，按照变量的类型进行初始化，比如static int a;如果不初始化，系统将初始化为0没有，直接报错

xiaruixiarui本版专家分：31结帖率：100%类的静态成员变量，为什么一定要初始化，而不是给一个默认初始值？为什么不能在类的声明中初始化呢？谢谢

谈完静态成员变量的性质以后，让我们来讨论一下为什么静态成员变量不能立即初始化，也就是像代码1那样去做。假设我们可以将静态成员变量立即初始化，那么代码3展开：// farm1.cpp    class Test {  public:     static int a = 0;  }    void fun() {     Test t;     t.a = 3;  }这里面的静态成员变量不再是一个声明，而是定义，当函数fun执行到"t.a = 3;"时，不会再把a当成为一个外部符号，不会把它放入未解决符号表中。a首先被赋值为0，然后被修改为3。再看以下代码：

可以看到int b = t.a;的汇编语句是：00411433 mov dword ptr [b],5这说明编译器已经对const int static a = 5；优化了。注意：只有静态常量整形数据成员才可以立即初始化。

qilimi10536209122015.10.29 17:43初始化就是第一次，难道你要很多第一次？？好吧！我有点邪恶了！静态全局变量有以下特点：1.该变量在全局数据区分配内存；2.未经初始化的静态全局变量会被程序自动初始化为03.静态全局变量在声明它的整个文件都是可见的，而在文件之外是不可见的；qq_271830032015.10.29 18:59在函数外定义全局变量时，可以初始化，也可以不初始化。在函数用这个变量时初始化也可以。但是不能在函数外单独写语句，类似 j=2;这是语法错误。所以第一个位置是语法错误。

在第二个位置可以有j=2;  除了定义变量等语句可以在函数外，其他普通语句必须在函数内。比如：你不能把pritf("ok"); 放到函数外。u0144933232015.10.29 17:37static声明个全局变量，所以在每个函数中调用都没问题，但是你在函数块外随便进行操作，恐怕编译器不能允许吧。qq_271830032015.10.29 19:09在全局变量前加static的作用：限制改变量只能在本文件可用，本文件之外是不可见的。和extern相对应。在函数内部定义变量前加static的作用：该变量是静态局部变量，在定义时就要初始化，且只执行一次初始化。

Evankaka2015.10.29 21:17静态变量(static).静态变量之所以是因为静态，是因为他在整个程序生命周期的地址静止不变。也就是说在整个程序里面只保存有一份拷贝。static关键字允许它在不同的函数调用间保持它的值。如果一个静态变量被访问后值改变，它就会保持新的值。如果这变量再次被访问，它将会维持最新的值tongyi555552015.10.31 16:04静态变量只是地址不会变，只初始化一次，C的不是很清楚。初始化这个东西有些时候看怎么理解了，Java中指类加载的时候。

静态变量初始化顺序1.简单规则首先先看一段最普遍的JAVA代码：public class Test  {   public static Test1 t = new Test1();   public static int a = 0;   public static int b;     public static void main(String[] arg)   {    System.out.println(Test.a);    System.out.println(Test.b);   }  }    class Test1  {   public Test1()   {    Test.a++;    Test.b++;   }  }

这里先猜下控制台输出结果是什么OK, 或许你已经猜到下面了结果了,那么你还是熟悉Java的。复制代码代码如下:0 1如果你不明白是为什么会输出上面的结果,那么我来告诉你。Java静态变量初始化遵循以下规则:静态变量会按照声明的顺序先依次声明并设置为该类型的默认值，但不赋值为初始化的值。声明完毕后,再按声明的顺序依次设置为初始化的值，如果没有初始化的值就跳过。看了这个就会明白,原来Test.a的值变化了三次。声明时设置为0>>Test1::Test1里设置为1>>Test.a初始化为02.复杂规则明白了这个，请再看下面的代码。

这个结果你没猜到吧,哈哈.要一句一句的讲解程序执行结果,还是要很到的篇幅的.这里就直接写出Java静态变量初始化遵循的规则了。第一段的规则依然有效，只是不健全。只有主动请求一个类,这个类才会初始化,仅包含静态变量,函数,等静态的东西.继承关系时,先初始化父类,后初始化子类.静态变量会按照声明的顺序先依次声明并设置为该类型的默认值,但不赋值为初始化的值.声明完毕后,再按声明的顺序依次设置为初始化的值,如果没有初始化的值就跳过.当初始化A.b=B.a时,暂停初始化A.b,设置当前类为B,跳到步骤3,并执行.当初始化B.plus = new A时,暂停初始化B.plus,实例化A并赋值给B.plus.

当A的构造函数里需要获得B.a的值时,B.a还初始化并处于暂停初始化状态,直接取B.a的当前值,不再等待B.a初始化.final,静态常量其实是遵循普通静态变量的初始化的,但是在编译时,编译器会将不可变的常量值在使用的地方替换掉.可以用Java反编译工具查看.static数据的初始化加上static限定的字段，是所谓的类字段，也就是说这个字段的拥有者不是对象而是类。无论创建多少对象，static数据都只有一份。类内总是先初始化static字段，再初始化一般字段。接着初始化构造器。但是如果不创建这个类的对象，那这个对象是不会进行初始化的，并且只执行一次。

如下面的代码，在StaticInitialization类中，先初始化static Table table = new Table();，然后才去初始化Table对象，不然是不会被初始化的。class Bowl {   Bowl(int marker) {   print("Bowl(" + marker + ")");   }   void f1(int marker) {   print("f1(" + marker + ")");   }  }    class Table {   static Bowl bowl1 = new Bowl(1);   Table() {   print("Table()");   bowl2.f1(1);   }   void f2(int marker) {   print("f2(" + marker + ")");   }   static Bowl bowl2 = new Bowl(2);  }    class Cupboard {   Bowl bowl3 = new Bowl(3);   static Bowl bowl4 = new Bowl(4);   Cupboard() {   print("Cupboard()");   bowl4.f1(2);   }   void f3(int marker) {   print("f3(" + marker + ")");   }   static Bowl bowl5 = new Bowl(5);  }    public class StaticInitialization {   public static void main(String[] args) {   print("Creating new Cupboard() in main");   new Cupboard();   print("Creating new Cupboard() in main");   new Cupboard();   table.f2(1);   cupboard.f3(1);   }   static Table table = new Table();   static Cupboard cupboard = new Cupboard();  }

输出：Bowl(1)  Bowl(2)  Table()  f1(1)  Bowl(4)  Bowl(5)  Bowl(3)  Cupboard()  f1(2)  Creating new Cupboard() in main  Bowl(3)  Cupboard()  f1(2)  Creating new Cupboard() in main  Bowl(3)  Cupboard()  f1(2)  f2(1)  f3(1)显示的静态初始化（也就是静态块）把多个初始化语句包在一个static花括号里，叫做静态块，其实就是把多个static合在一起写了，本质是一样的。只有首次创建对象或者首次访问类的字段时才会执行，而且仅仅一次。

输出：Inside main()  Cup(1)  Cup(2)  f(99)非静态实例初始化这个没什么好讲的，就是普通初始化，按顺序执行，可以多次执行。class Mug {   Mug(int marker) {   print("Mug(" + marker + ")");   }   void f(int marker) {   print("f(" + marker + ")");   }  }    public class Mugs {   Mug mug1;   Mug mug2;   {   mug1 = new Mug(1);   mug2 = new Mug(2);   print("mug1 & mug2 initialized");   }   Mugs() {   print("Mugs()");   }   Mugs(int i) {   print("Mugs(int)");   }   public static void main(String[] args) {   print("Inside main()");   new Mugs();   print("new Mugs() completed");   new Mugs(1);   print("new Mugs(1) completed");   }  }