本文转自此处
源代码:
public class Teststaticblock { public Teststaticblock() { this("second"); System.out.println("begin constructor"); System.out.println(s_a); //111 System.out.println(s_b); //222 System.out.println(c); //333 System.out.println(d); //d的值为什么是4,却不是444?? //因为程序会按照初始化块和实例Field生命语句的先后顺序来执行, //先赋给d的值444会被后赋给d的值4覆盖掉,所以d的最终值为4. // this("second");//call to this must be first statement in constructor s_a=1111; s_b=2222; c=3333; d=4444; System.out.println(s_a); //1111 System.out.println(s_b); //2222 System.out.println(c); //3333 System.out.println(d); //4444 System.out.println("end constructor"); } public Teststaticblock(String s) { System.out.println("begin second constructor"); System.out.println("end second constructor"); } public static void main(String args[]) { System.out.println("begin main"); System.out.println(s_a); System.out.println(s_b); //s_b的值为什么是2,却不是22?? //因为程序会按照静态初始化块和静态Field声明语句的先后顺序来执行,先赋给s_b的值22 //会被后赋给s_b的值2覆盖掉,所以s_b最终的值为2. // System.out.println(c); //non-static variable c cannot be referenced from a static context // System.out.println(d); //non-static variable c cannot be referenced from a static context s_a=11111; s_b=22222; // c=33333;//non-static variable c cannot be referenced from a static context // d=44444;//non-static variable c cannot be referenced from a static context System.out.println(s_a); //11111 System.out.println(s_b); //22222 // System.out.println(c); //non-static variable c cannot be referenced from a static context // System.out.println(d); //non-static variable c cannot be referenced from a static context System.out.println("before new class object"); Teststaticblock t = new Teststaticblock(); System.out.println("end new class object"); System.out.println(s_a);//1111 System.out.println(s_b); //2222 // System.out.println(c); //non-static variable c cannot be referenced from a static context // System.out.println(d); //non-static variable c cannot be referenced from a static context s_a=111111; s_b=222222; // c=333333;//non-static variable c cannot be referenced from a static context // d=444444;//non-static variable c cannot be referenced from a static context System.out.println(s_a); //111111 System.out.println(s_b); //222222 // System.out.println(c); //non-static variable c cannot be referenced from a static context // System.out.println(d); //non-static variable c cannot be referenced from a static context System.out.println("end main"); } static int s_a=1; int c=3; { System.out.println("begin block"); System.out.println(s_a); //11111 System.out.println(s_b); //22222 System.out.println(c); //3 // System.out.println(d);//illegal forward reference s_a=111; s_b=222; c=333; d=444; System.out.println(s_a); //111 System.out.println(s_b); //222 System.out.println(c); //333 // System.out.println(d);//illegal forward reference System.out.println("end block"); } static { System.out.println("begin static block"); //begin static block System.out.println(s_a);//1 //为什么不能输出s_b的值,却可以给s_b赋值?? // System.out.println(s_b);//illegal forward reference // System.out.println(c); //non-static variable c cannot be referenced from a static context // System.out.println(d); //non-static variable c cannot be referenced from a static context s_a=11; s_b=22; System.out.println(s_a); //11 // System.out.println(s_b);//illegal forward reference // System.out.println(c); //non-static variable c cannot be referenced from a static context // System.out.println(d); //non-static variable c cannot be referenced from a static context System.out.println("end static block"); } int d=4; static int s_b=2; }
运行结果:
/* begin static block 1 11 end static block begin main 11 2 11111 22222 before new class object begin block 11111 22222 3 111 222 333 end block begin second constructor end second constructor begin constructor 111 222 333 4 1111 2222 3333 4444 end constructor end new class object 1111 2222 111111 222222 end main */
结果分析:
1、在类第一次加载时候,会执行静态成员变量(静态Field)初始化语句和静态初始化块(用static{}包含的部分)。
注意:
a、不管静态成员变量声明语句的实际位置在哪儿,当第一次加载类的时候都会首先对它初始化为缺省值(0,false,null等)。
b、即使静态成员变量声明中使用了显式初始化语句(比如:int x=3),第一次加载类的时候也会先把它初始化为缺省值(此时x为0),然后再按照下面说的要点c来执行赋值语句(x=3)。
c、对于静态成员变量的显式初始化语句和静态初始化块,按照在类中代码出现的先后顺序执行。
因此,在上面的例子程序中,我们看到
static int s_a=1;
static
{
s_a=11;
s_b=22;
}
static int s_b=2;
对s_a,s_b会有不同的效果。
类加载时候,s_a,s_b都被初始化为0,然后由于依照代码顺序执行了s_a=1;s_a=11;s_b=22;s_b=2;
结果s_a、s_b分别变成了11和2。
2、当构造类实例时候,会先对实例成员变量初始化为缺省值,然后执行初始化块(用{}括起来的部分),然后执行构造方法。其中:
a、如同1中一样,如果有实例成员变量的显式初始化语句,程序仍然是先将该成员变量初始化为缺省值,然后按照代码在类中出现的先后顺序执行初始化语句或者初始化块。
如果初始化块位置在初始化语句前面,即使它改变了该成员变量的值,也会被随后执行的初始化语句改回去。
b、在进入构造方法后,如果构造方法第一句是使用this(...)调用另一构造方法的话,则先执行另一构造方法,然后再执行本构造方法的方法体。这种用法必须让this(...)位于第一句。
相关推荐
System.out.println("父类--静态初始化块"); } // 初始化块 { System.out.println(p_Field); System.out.println("父类--初始化块"); } // 构造器 public Parent() { System.out.println(...
1.只能在构造函数初始化列表初始化的成员变量的类型? a.const成员变量 b.引用类型的成员变量 c.static不能在初始化列表中进行初始化 d.类成员变量中有自定义类型的变量最好在初始化列表中进行初始化 2.初始...
static所声明的变量在Java中有一个初始化的先后顺序,带着这个问题接下来我们就来进行Java中static静态变量的初始化完全解析:
考虑一下效率的可以再构造函数的初始化列表中进行。 class CA { public: int data; …… public: CA(); …… }; CA::CA():data(0)//……#1……初始化列表方式 { //data = 0;//...
不要把static成员变量的初始化操作安排在类的构造函数中,因为构造函数可能一再被调用,而static成员变量只实例化一次。也不要把初始化操作安排在头文件中,因为它可能会被载入许多地方,因此也就可能被执行多次。...
C++ 成员变量的初始化顺序问题详解 问题来源: 由于面试题中,考官出了一道简单的程序输出结果值的题:如下, class A { private: int n1; int n2; public: A():n2(0),n1(n2+2){} void Print(){ cout <&...
当我们想初始化一些静态变量的时候,就需要用到静态构造函数了。这个静态构造函数属于类,而不属于实例,就是说这个构造函数只会被执行一次,即:在创建第一个实例或引用任何静态成员之前,由.NET自动调用。 现在...
当我们想初始化一些静态变量的时候,需要用到静态构造函数了。这个静态构造函数属于类,而不属于实例,是说这个构造函数只会被执行一次,即:在创建第一个实例或引用任何静态成员之前,由.NET自动调用。 现在碰到...
无论是类成员(静态变量)合适实例变量,我们都应该充分利用初始化器的语法。 C#编程在,一般在声明一个变量的同时我们会对其进行初始化: 代码如下:1 class Employee 2 { 3 private List<Employee> empList = new ...
使用 static 修饰符声明属于类型本身而不是属于特定对象的静态成员static修饰符可用于类、字段、方法、属性、运算符、事件和构造函数,但不能用于索引器、析构函数或类以外的类型 静态全局变量 定义:在全局变量...
以下这段小程序对调用对象构造函数时,父类构造函数、成员变量初始化函数,以及非静态初始化块调用顺序进行验证,不考虑静态成员及静态初始化块
(3)类的静态构造函数在给定应用程序域中至多执行一次:只有创建类的实例或者引用类的任何静态成员才激发静态构造函数 (4)静态构造函数是不可继承的,而且不能被直接调用。 (5)如果类中包含用来开始执行的...
不过当我们想初始化一些静态变量的时候就需要用到它了。这个构造函数是属于类的,而不是属于哪里实例的,就是说这个构造函数只会被执行一次。也就是在创建第一个实例或引用任何静态成员之前,由.NET自动调用。 代码...
类的静态构造方法是类的成员方法的一种,它的作用是对类中的静态成员进行初始化操作。下面请看代码实例: using System; namespace LycheeTest { class Test { //定义一个静态成员变量 private static int a; /...
声明、初始化并使用基本类型、数组、枚举、静态对象、成员变量和局部变量,使用合法的变量标识符。 定义方法和静态方法,使用符合JavaBean命名规范的方法名。 定义并使用可变参数。正确重写和重载方法并识别...
静态初始化的数组的长度必须是在程序中确定的常数,不能是由用户输入的变量 例子: int a[10];//正确 Student stud[10];//正确:Student是一个学生类 int n;cin>>n;int a[n];//错误 int n;cin>>n;Student stud[n];/...
构造函数的作用是对对象本身做初始化工作,也就是给用户提供初始化类中成员变量的一种方式,在类对象有虚表的情况下,构造函数还对虚表进行初始化。 另外,我说:“C++又规定,如果一个类没有提供任何的构造函数,则...
9.4 静态初始化的依赖因素 9.5 转换连接指定 9.6 小结 9.7 练习 第10章 引用和拷贝构造函数 10.1 C++中的指针 10.2 C++中的引用 10.2.1 函数中的引用 10.2.2 参数传递准则 10.3 拷贝构造函数 10.3.1 传值...
在InitInstance()函数中,创建了一个单文档模板类或多文档模板类(CDocTemplate)的对象,并且在文档模板的构造函数中,系统定义的宏RUNTIME_CLASS创建了文档类对象,框架窗口类对象和视图类对象. 在MFC应用程序中有且仅有...
使用静态构造函数来初始化静态成员变量 14.用多个构造函数时,利用构造函数链 15.使用using和try/finally来处理资源的释放 16.尽量避免产生资源垃圾 17.尽量避免使用装箱(boxing)和拆箱(unboxing) 18.实现...