精华内容
下载资源
问答
  • 静态变量初始化

    千次阅读 2014-02-27 11:17:29
    我们大家都知道,对于静态变量、静态初始化块、变量、初始化块、构造器,它们的初始化顺序以此是(静态变量、静态初始化块(顺序按声明顺序))>(变量、初始化块)>构造器。我们也可以通过下面的测试代码来验证这...
    我们大家都知道,对于静态变量、静态初始化块、变量、初始化块、构造器,它们的初始化顺序以此是(静态变量、静态初始化块(顺序按声明顺序))>(变量、初始化块)>构造器。我们也可以通过下面的测试代码来验证这一点: 
    Java代码 
    public class InitialOrderTest { 

    // 静态变量 
    public static String staticField = "静态变量"; 
    // 变量 
    public String field = "变量"; 

    // 静态初始化块 
    static { 
    System.out.println(staticField); 
    System.out.println("静态初始化块"); 


    // 初始化块 

    System.out.println(field); 
    System.out.println("初始化块"); 


    // 构造器 
    public InitialOrderTest() { 
    System.out.println("构造器"); 


    public static void main(String[] args) { 
    new InitialOrderTest(); 



    运行以上代码,我们会得到如下的输出结果: 

    静态变量 
    静态初始化块 
    变量 
    初始化块 
    构造器 

    这与上文中说的完全符合。那么对于继承情况下又会怎样呢?我们仍然以一段测试代码来获取最终结果: 
    Java代码 
    class Parent { 
    // 静态变量 
    public static String p_StaticField = "父类--静态变量"; 
    // 变量 
    public String p_Field = "父类--变量"; 

    // 静态初始化块 
    static { 
    System.out.println(p_StaticField); 
    System.out.println("父类--静态初始化块"); 


    // 初始化块 

    System.out.println(p_Field); 
    System.out.println("父类--初始化块"); 


    // 构造器 
    public Parent() { 
    System.out.println("父类--构造器"); 



    public class SubClass extends Parent { 
    // 静态变量 
    public static String s_StaticField = "子类--静态变量"; 
    // 变量 
    public String s_Field = "子类--变量"; 
    // 静态初始化块 
    static { 
    System.out.println(s_StaticField); 
    System.out.println("子类--静态初始化块"); 

    // 初始化块 

    System.out.println(s_Field); 
    System.out.println("子类--初始化块"); 


    // 构造器 
    public SubClass() { 
    System.out.println("子类--构造器"); 


    // 程序入口 
    public static void main(String[] args) { 
    new SubClass(); 



    运行一下上面的代码,结果马上呈现在我们的眼前: 

    父类--静态变量 
    父类--静态初始化块 
    子类--静态变量 
    子类--静态初始化块 
    父类--变量 
    父类--初始化块 
    父类--构造器 
    子类--变量 
    子类--初始化块 
    子类--构造器 

    现在,结果已经不言自明了。大家可能会注意到一点,那就是,并不是父类完全初始化完毕后才进行子类的初始化,实际上子类的静态变量和静态初始化块的初始化是在父类的变量、初始化块和构造器初始化之前就完成了。 

    那么对于静态变量和静态初始化块之间、变量和初始化块之间的先后顺序又是怎样呢?是否静态变量总是先于静态初始化块,变量总是先于初始化块就被初始化了呢?实际上这取决于它们在类中出现的先后顺序。我们以静态变量和静态初始化块为例来进行说明。 

    同样,我们还是写一个类来进行测试: 
    Java代码 
    public class TestOrder { 
    // 静态变量 
    public static TestA a = new TestA(); 

    // 静态初始化块 
    static { 
    System.out.println("静态初始化块"); 


    // 静态变量 
    public static TestB b = new TestB(); 

    public static void main(String[] args) { 
    new TestOrder(); 



    class TestA { 
    public TestA() { 
    System.out.println("Test--A"); 



    class TestB { 
    public TestB() { 
    System.out.println("Test--B"); 



    运行上面的代码,会得到如下的结果: 

    Test--A 
    静态初始化块 
    Test--B 

    大家可以随意改变变量a、变量b以及静态初始化块的前后位置,就会发现输出结果随着它们在类中出现的前后顺序而改变,这就说明静态变量和静态初始化块是依照他们在类中的定义顺序进行初始化的。同样,变量和初始化块也遵循这个规律。 

    了解了继承情况下类的初始化顺序之后,如何判断最终输出结果就迎刃而解了。
    展开全文
  • 今天,我们来探讨交流下静态变量初始化过程。Java虚拟机在类加载期间也同样遵循这个过程。2. 初始化过程在较高的层次上,JVM执行以下步骤:首先,加载并链接类。然后,这个过程的“初始化”阶段处理静态变量初始化。...

    1. 开始吧!

    今天,我们来探讨交流下静态变量初始化过程。Java虚拟机在类加载期间也同样遵循这个过程。

    2. 初始化过程

    在较高的层次上,JVM执行以下步骤:

    089f4263dd45d57c4aaa560453a4467f.png

    首先,加载并链接类。然后,这个过程的“初始化”阶段处理静态变量初始化。最后,调用与类关联的main方法。

    在接下来的讨论中,我们来探索下类变量初始化。

    3. 类变量

    在Java中,静态变量也称为类变量。也就是说,它们属于一个类,而不是一个特定的实例。因此,类初始化的时候也将初始化静态变量

    相反,类的实例 初始化的时候也将初始化 实例变量(非静态变量)。类的所有实例共享该类的静态变量。

    以 StaticVariableDemo 类为例:public class StaticVariableDemo {

    public static int i;

    public static int j = 20;

    public StaticVariableDemo() {}

    }

    First, the JVM creates a Class object for the class StaticVariableDemo. Next, the static field initializers assign a meaningful default value to the static fields. In our example above, the class variable i is first initialized with an int default value of zero.

    首先,JVM为 StaticVariableDemo 类创建一个Class对象。接下来,static 修饰的字段将会被赋予一个有意义的默认值。在上面的例子中,类变量 i 首先使用用 int 的默认值0 来初始化。

    代码的书写顺序适用于静态字段初始化顺序。首先,i将初始化,然后j将被初始化。完成初始化之后,类及其静态成员将对其他类可见。

    4. 静态块中的变量

    再举一个例子:public class StaticVariableDemo {

    public static int z;

    static {

    z = 30;

    }

    public StaticVariableDemo() {}

    }

    在这种情况下,变量初始化将按顺序进行。首先,JVM最初将默认的int值0赋给变量z。然后,在static块中,它被更改为30。

    5. 静态嵌套类中的变量

    最后,让我们以外部 StaticVariableDemo 类中的嵌套类为例:public class StaticVariableDemo {

    public StaticVariableDemo() {}

    static class Nested {

    public static String nestedClassStaticVariable = "test";

    }

    }

    在本例中,StaticVariableDemo 类加载 Nested 类。它将初始化静态变量 nestedClassStaticVariable。

    6. 最后

    在这篇短文中,我们简要地解释了静态变量初始化。有关详细信息,请查看 Java语言规范.

    如果你觉得文章还不错,记得关注公众号: 锅外的大佬

    刘一手的博客

    展开全文
  • 全局变量、文件域的静态变量和类的静态成员变量在main执行之前的静态初始化过程中分配内存并初始化;局部静态变量(一般为函数内的静态变量)在第一次使用时分配内存并初始化。这里的变量包含内置数据类型和自定义...

    全局变量、文件域的静态变量和类的静态成员变量在main执行之前的静态初始化过程中分配内存并初始化;局部静态变量(一般为函数内的静态变量)在第一次使用时分配内存并初始化。这里的变量包含内置数据类型和自定义类型的对象。

    class B{
    public:
    	B()
    	{
    		cout << "B constructor called" << endl;
    	}
    	~B()
    	{
    		cout << "B desconstructor called" << endl;
    	}
    };
    class A{
    public:
    	A()
    	{
    		cout << "A constructor called" << endl;
    	}
    	~A()
    	{
    		cout << "A desconstructor called" << endl;
    	}
    private:
    	static B b;
    };
    
    class C{
    public:
    	C()
    	{
    		cout << "C constructor called" << endl;
    	}
    	~C()
    	{
    		cout << "C desconstructor called" << endl;
    	}
    };
    class D{
    public:
    	D()
    	{
    		cout << "D constructor called" << endl;
    	}
    	~D()
    	{
    		cout << "D desconstructor called" << endl;
    	}
    };
    class E{
    public:
    	E()
    	{
    		cout << "E constructor called" << endl;
    	}
    	~E()
    	{
    		cout << "E desconstructor called" << endl;
    	}
    };
    int f()
    {
    	system("pause");
    	return 0;
    }
    C c;
    static E e;
    B A::b = B();//静态成员变量在类外初始化
    int main()
    {
    	_onexit(f);
    	A *pa = new A;
    	B b;
    	static D d;
    	delete pa;
    	return 0;
    }
    输出:

    C constructor called//全局变量初始化在main执行之前
    E constructor called//全局静态变量初始化在main之前

    B constructor called//类中的静态成员变量在类外初始化在main之前

    A constructor called//main中执行A的默认构造函数,但是没有调用B的默认构造函数,(若A中的成员变量b不是static型的,那么在调用A的构造函数                                                                                                             时,系统会调用B的默认构造函数,这里涉及到构造函数成员初始化列表的作用)

    B constructor called//构造b

    D constructor called//局部静态变量在第一次使用时初始化

    A desconstructor called//显示调用A的析构

    B desconstructor called//局部变量在栈上,早析构

    D desconstructor called//局部静态变量出了main后析构

    B desconstructor called//类的静态成员变量析构

    E desconstructor called//全局静态变量析构

    C desconstructor called//全局变量析构,这后边三个析构顺序,应该和它们的构造顺序相反!!!!

    下边内容转载:

    有些成员变量的数据类型比较特别,它们的初始化方式也和普通数据类型的成员变量有所不同。这些特殊的类型的成员变量包括:

    a.引用

    b.常量

    c.静态

    d.静态常量(整型)

    e.静态常量(非整型)

    常量和引用,必须通过参数列表进行初始化。这里不包括常量静态成员变量,因为无法通过构造函数初始化静态类数据。但是非常量静态类数据,可以通过构造函数体赋值。

    例如:

    class Test {
    public:
    	int a;
    	static int b;
    public:
    	Test(int _a, int _b) : a(_a){
    		b = _b;
    	}
    };
    int Test::b;
    int main() {
    	Test t1(0, 0), t2(1, 1);
    	t1.b = 10;
    	t2.b = 20;
    	printf("%u %u %u %u", t1.a, t1.b, t2.a, t2.b);
    	system("pause");
    	return 0;
    }
    但如果是常量静态类数据就不行了,因为不能对常量赋值。

    静态成员变量的初始化也颇有点特别,是在类外初始化且不能再带有static关键字,记住是类外初始化,但可以在构造函数中赋值,其本质见文末。

    参考下面的代码以及其中注释:

        #include   
        using namespace std;  
          
        class BClass  
        {  
        public:  
         BClass() : i(1), ci(2), ri(i){} // 对于常量型成员变量和引用型成员变量,必须通过参数化列表的方式进行初始化  
                                                        //普通成员变量也可以放在函数体里,但是本质其实已不是初始化,而是一种普通的运算操作-->赋值运算,效率也低  
        private:  
         int i;                                  // 普通成员变量  
         const int ci;                           // 常量成员变量  
         int &ri;                                // 引用成员变量  
         static int si;                          // 静态成员变量  
         //static int si2 = 100;                 // error: 只有静态常量成员变量,才可以这样初始化  
         static const int csi;                   // 静态常量成员变量  
         static const int csi2 = 100;            // 静态常量成员变量的初始化(Integral type)    (1)  
         static const double csd;                // 静态常量成员变量(non-Integral type)  
         //static const double csd2 = 99.9;      // error: 只有静态常量整型数据成员才可以在类中初始化  
        };  
          
        //注意下面三行:不能再带有static  
        int BClass::si = 0; // 静态成员变量的初始化(Integral type)  
        const int BClass::csi = 1; // 静态常量成员变量的初始化(Integral type)  
        const double BClass::csd = 99.9; // 静态常量成员变量的初始化(non-Integral type
    静态成员属于类作用域,但不属于类对象,和普通的static变量一样,程序一运行就分配内存并初始化,生命周期和程序一致。
    所以,在类的构造函数里初始化static变量显然是不合理的。
    静态成员其实和全局变量地位是一样的,只不过编译器把它的使用限制在类作用域内(不是类对象,它不属于类对象成员),要在类的定义外(不是类作用域外)初始化。

    下面再说说成员变量是引用的情况:

    因为引用是别名的意思,所以定义应用肯定是外部有定义,然后在构造函数初始化列表中被初始化的。

    如果两个类要对第三个类的数据进行共享处理,可以考虑把第三个类作为这两个类的引用类型的成员变量。

    展开全文
  • Java静态变量初始化时机

    千次阅读 2015-06-05 10:55:17
    静态变量初始化方式: 1.声明时初始化; 2.静态块中初始化; 测试: package com.skymr.learn; /** * 静态变量初始化顺序测试 * @author skymr * */ public class InstanceTest2 { static int b = 11; ...

    静态变量初始化方式:

    1.声明时初始化;

    2.静态块中初始化;

    测试:

    package com.skymr.learn;
    /**
     * 静态变量初始化顺序测试
     * @author skymr
     *
     */
    public class InstanceTest2 {
    
    	static int b = 11;
    	
    	static{
    		a = 20;
    		b = 22;
    	}
    	
    	static int a = 10;
    	
    	public static void main(String[] args) throws Exception{
    		System.out.println("a="+InstanceTest2.a);
    		System.out.println("b="+InstanceTest2.b);
    	}
    }
    
    结果:

    a=10
    b=22
    
    测试证明:1,2的先后顺序依靠代码的前后排列


    问题:静态变量的初始化是什么时候开始的呢?

    package com.skymr.learn;
    /**
     * 静态变量初始化顺序测试
     * @author skymr
     *
     */
    public class InstanceTest2 {
    
    	static int b = 11;
    	
    	static{
    		System.out.println("静态块");
    		a = 20;
    		b = 22;
    	}
    	
    	static int a = 10;
    	
    	public static void nop(){
    	}
    	
    }
    

    Main方法移出来了

    package com.skymr.learn;
    
    
    public class MainTest {
    public static void main(String[] args) throws Exception{
    System.out.println("main方法开始"); //step1
    InstanceTest2.nop();//step2
    System.out.println("main方法开始--");//step3
    System.out.println("a="+InstanceTest2.a);
    System.out.println("b="+InstanceTest2.b);
    }
    }
    
    打印结果:

    main方法开始
    静态块
    main方法开始--
    a=10
    b=22

    分析:执行step1时InstanceTest2类还没有装载进内存,也就没有运行它的静态块代码;

       当调InstanceTest2.nop方法时,开始将InstanceTest2类载入内存,装载完成后开始自动运行静态变量的声明代码和静态块

              也就是说静态变量是在载入内存后初始化的;
    再一示例:

    package com.skymr.learn;
    
    public class InstanceTest3 {
    	
    	
    	public static void main(String[] args){
    		Person son = new Person(5);
    		System.out.println(son.parent.value);
    		System.out.println(son.value);
    	}
    }
    
    class Person{
    	final static Person parent = new Person(2); //1
    	static int age = 30; //2
    	int value;
    	public Person(int delta){
    		value = age + delta;
    	}
    }
    

    打印 出:

    2
    35
    
    分析:new Person时最先执行 1,此时age=0, 所以son.parent.value = 0 + 2 = 2;
         执行完2后,才会进行son的构造方法,所以age = 30;value也就为35了.


    展开全文
  • 关于C++中类中类的静态变量,或者说类中结构体中的静态变量的初始化问题,解释如下: ...2.类或结构的静态变量初始化必须在外部,这个外部是哪里呢? 上面这是test.h,这里定义了静态变量x,那么我...
  • Java静态变量初始化的坑

    千次阅读 2019-03-02 21:55:15
    Java静态变量初始化的坑 如图所示的代码 class SingleTon { private static SingleTon singleTon = new SingleTon(); public static int count1; public static int count2 = 1; private SingleTon...
  • Spring框架给类的静态变量初始化

    千次阅读 2018-11-27 19:33:57
    工作中遇到一个问题给工具类静态变量初始化,就记录了一下。 这里需要注意一下不可以直接使用@Value注解的方式给静态变量初始化赋值; 1.第一种是用spring配置文件 下面是java类,其中注释的注解是试验注解方式,...
  • 在工具类中,通常会初始化一些单例变量,这些变量由于只会初始一次,并不适合放在构造函数中,因此通常选择在静态代码块中执行,那么在一个类中,就会涉及到静态变量和静态代码块的初始化执行顺序问题。 public ...
  • 单例模式中静态变量初始化与不初始化有什么区别?  public class Singleton {  private static Singleton obj = new Singleton();  public static int counter1;  public static int counter2 = 0;  ...
  • STL编程之--静态变量初始化方法

    千次阅读 2013-09-27 16:16:10
    静态变量在STL模板编程中,总是让新手摸不着头脑,STL奇奇怪怪的语法再加上初始化的特定...在普通类中定义的静态变量初始化。 2. 在STL模板中定义的静态变量初始化。下面将分别说明在这两种情况下,应该如何正确的初
  • 静态变量的内存分配和初始化 对于C语言的全局和静态变量,不管是否被初始化,其内存空间都是全局的;如果初始化,那么初始化发生在任何代码执行之前,属于编译期初始化。由于内置变量无须资源释放操作,仅需要回收...
  • 静态变量初始化与线程安全

    千次阅读 2019-01-03 17:47:36
    但是老的c++标准并没有担保,所以说老版本的编译器可能static 变量初始化在多线程的条件下会造成问题 c++ 98/03 关于静态初始化标准 简言而之,它只是担保了local static 变量的初始化发生于当该表达式第一次执行...
  • 【1】C++函数内的静态变量初始化以及线程安全问题 (1)如果是编译时和加载时初始化, 是不会存在线程安全问题的; 因为这两种初始化一定发生在Main函数执行之前, 这个时候尚未进入程序运行空间; 而这些初始化一定...
  • java构造方法、静态变量初始化顺序的小例子题目来自:https://www.nowcoder.com/test/question/done?tid=10095249&qid=56443#summary以下代码输出的结果是:class Singleton { private static Singleton obj = new ...
  • C++全局和静态变量初始化顺序的研究 我在编程的时候遇到了一个非常棘手的问题,就是静态变量初始化的问题。有的情况一个全局(静态)变量依赖另外一个全局(静态)的变量。比如在工厂模式中使用隐式注册注册一个...
  • c++中可以对类中私有成员中的静态变量初始化吗? 我看的书上写的对私有部分的访问可以是公共部分的成员函数,也可以是友员函数,那么可以直接对私有部分的静态成员进行初始化吗? 我来答 分享 举报 4个回答 ...
  • 类B使用了信号和槽,此时运行程序出现崩溃,经排查VS工程文件中先编译类A的文件,后编译类B的moc文件,程序运行时先初始化类A的全局变量,此时类Bmoc的元对象静态成员未初始化,类似于moc_xxx.cpp文件中的static ...
  • 静态方法只能访问类的静态成员,不能访问类的非... 静态变量当然是属于静态存储方式,但是属于静态存储方式的量不一定就是静态变量,例如外部变量虽属于静态存储方式,但不一定是静态变量,必须由 static加以定义后才能
  • 静态变量的内存分配和初始化 c 对于C语言的全局和静态变量,不管是否被初始化,其内存空间都是全局的;如果初始化,那么初始化发生在任何代码执行之前,属于编译期初始化。由于内置变量无须资源释放操作,仅需要...
  • C语言静态变量初始化问题

    千次阅读 2018-02-10 12:45:45
    书上的解释是,用static修饰的变量会自动初始化。  为什么会被初始化呢?首先我们看一段话: 可执行程序和内存映像的区别在于:可执行程序位于磁盘上,内存映像位于内存中,可执行程序没有堆栈,可执行程序虽然也...
  • java静态变量初始化

    2016-08-22 12:14:16
    直接上代码(Java程序员的基本修养示例) class Price ... //定义一个初始化变量 static double initPrice = 20; //定义当前价格 double currentPrice; public Price(double discount) { Sys
  • 静态变量 undefined reference 1. c++头文件, 类中定义static 变量,不要在头文件内类外做初始化(头文件被多次包含,会引起多重定义),也不能在构构函数内初始化。 (1.对于类中的静态成员是单独存储的,而不是...
  • class Bowl{ Bowl(int marker){ System.out.println(“Bowl(” + marker + “)”); } void f1(int marker) { System.out.println(“f1(” + marker + “)”); } } class Table{ ...
  • Java 类初始化顺序在网上已经有很多文章了,这里不再谈那么多,仅仅谈下Java静态变量初始化顺序,如果你是Java高手,并且自认为对这个顺序已经掌握到了炉火纯青的境界,请忽视这篇文章. 前天看了Y.BOY对AS程序员的...
  • 1.全局变量 全局变量无疑要在main函数开始前执行完成,但可细分为在编译时和在运行时初始化,即static initialization和dynamic initialization。 static initialization 静态初始化按照我的理解,是针对那些较为...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 19,270
精华内容 7,708
关键字:

静态变量初始化