关于静态数据的初始化顺序问题

//代码如下,摘自java编程思想:

class Bowl {

Bowl(int maker) {

System.out.println("Bowl(" + maker + ")");

}

void f1(int maker) {

System.out.println("f1(" + maker + ")");

}

}

class Table {

static Bowl bowl1 = new Bowl(1);

Table() {

System.out.println("Table()");

bowl2.f1(1);

}

void f2(int maker) {

System.out.println("f2(" + maker + ")");

}

static Bowl bowl2 = new Bowl(2);

}

class Cupboard {

Bowl bowl3 = new Bowl(3);

static Bowl bowl4 = new Bowl(4);

Cupboard() {

System.out.println("Cupboard()");

bowl4.f1(2);

}

void f3(int maker) {

System.out.println("f3(" + maker + ")");

}

static Bowl bowl5 = new Bowl(5);

}

public class StaticInitialization {

public static void main(String[] args) {

System.out.println("Creating new Cupboard() in main");

new Cupboard();

System.out.println("Creating new Cupboard() in main");

new Cupboard();

table.f2(1);

cupboard.f3(1);

}

static Table table = new Table();

static Cupboard cupboard = new Cupboard();

}

output:

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)

初学者或基础不牢的同学(比如我自己= =\)可能看见这个程序会有点晕,为什么输出的结果是这么个顺序?

要了解静态存储区域是何时初始化的。人人都知道一个程序是从main()方法开始的,但是如果直接着手main方法开始进入程序,那么得出的output就不是正确的了。这里涉及到类加载的问题。

首先得知道初始化的顺序:1.先静态对象 2.非静态对象 。

在Table类和Cupboard类里面加入了Bowl类型的静态成员变量,而且只有在第一个Table对象被创建的时候,它们才会被初始化,并且只能被初始化一次。

从output观察:要想执行main方法,必须要加载StaticInitialization类,然后静态域table 、cupboard被初始化,即它们对应的类被加载,并且Table类和Cupboard类里包含静态的Bowl对象,所以Bowl类也被加载,即在main()方法开始之前这几个类都被加载了。所以,输出结果的顺序就明白了吧。

需要注意的地方就三点:1.先静态对象,后非静态对象;

           2.静态对象只能被初始化一次(output里面的Bowl(1)、2、4、5只出现一次,而Bowl(3)出现了两次,因为new了两个Cupboard()对象);

           3.所有的事物通过static联系到了一起...

以上总结是个人理解及书上的解释,若有错误请指正、各位大神多多包涵!本人Java小白,愿与大家多交流学习。

时间: 2024-10-05 04:43:28

关于静态数据的初始化顺序问题的相关文章

C++类中常量数据成员和静态数据成员初始化

常量数据成员初始化原则: 在每一个构造函数的初始化列表中初始化 静态数据成员初始化原则: 类内声明,类外初始化(因为它是属于类的,不能每构造一个对象就初始化一次) // test_max.cpp : 定义控制台应用程序的入口点. #include "stdafx.h" #include <iostream> #include <vector> using namespace std; class A { public: A(int i):a(0) {} A():

static静态数据的初始化

package com.demo.book; public class StaticInitialization { static Table table = new Table(); static Cupboard cupboard = new Cupboard(); public static void main(String[] args) { new Cupboard(); new Cupboard(); table.f2(3); cupboard.f3(1); } } class Bo

[百度空间] [原]再谈静态变量的初始化顺序

有一段时间我被静态变量的初始化顺序搞的焦头烂额,因为我用了singleton的懒惰初始化(lazy initialization)方式,即不需要显式创建singleton,在getsignleton的时候自动创建,并且在最后销毁对象..比如singleton使用了内存分配对象,如果这个对象先于singleton析构(后于singleton构造),那么singleton析构的时候内存分配器已经不存在了.最后发现我忽略了effctive C++的条款47,看来很多细节还是不是很深入的领悟. 关于其中

JAVA编程思想(第4版) 静态数据的初始化

无论创建多少个对象,静态数据永远只占用一份存储空间.static关键字不能应用于局部变量,因此它只能作用于域.如果一个域是静态的基本类型域,且没有对它进行初始化,那么它就会获得基本类型的标准初值,而如果它是一个对象的引用,则默认初始值为null.例子如下: package test; class Bowl{ Bowl(int marker){ System.out.println("Bowl("+marker+")"); } void f1(int marker){

静态数据的初始化

package me.ybleeho; class Bowl{ Bowl(int marker){ System.out.println("Bowl"+marker); } void f1(int marker){ System.out.println("f1"+marker); } } class Table{ static Bowl bowl1=new Bowl(1); Table(){ System.out.println("Table()"

类的静态数据成员初始化问题

1. 静态数据成员在类声明中声明,在包含类方法的文件中初始化.初始化时使用作用域运算符来指出静态成员所属的类.但如果静态成员是整形const或枚举型const,则可以在类声明中初始化. C++ primer plus P426-P427类静态成员的声明和初始化 //strnbad.h class StringBad { private: static int num_strings; … }; //strnbad.cpp int StringBad::num_strings = 0; 不能在类声

Java初始化顺序

1.在类的内部,变量的定义的先后顺序决定了初始化顺序,即使变量定义散布于方法定义间,他们仍旧会在任何方法(包括构造器)被调用之前得到初始化 2.静态数据的初始化 class Bowl{ Bowl(int marker){ print("Bowl("+marker+")"); } void f1(int marker){ print("f1("+marker+")"); } class Table{ static Bowl bo

c++:静态数据成员

一 . 静态数据成员 类体中的数据成员的声明前加上static关键字,该数据成员就成为了该类的静态数据成员.和其它数据成员一样,静态数据成员也遵守public/protected/private访问规则.同时,静态成员还具有以下特点: 1. 静态数据成员的定义. 静态数据成员实际上是类域中的全局变量.所以,静态数据成员的定义不应该被放在头文件中.静态数据成员初始化时不受private和protected访问限制. 注意:不要试图在头文件中定义静态数据成员.在大多数情况下,这样做会引起重复定义这样

C++成员变量的初始化顺序问题

转载自:http://www.cnblogs.com/lidabo/p/3790606.html ,感谢作者! 问题来源: 由于面试题中,考官出了一道简单的程序输出结果值的题:如下, class A { private: int n1; int n2; public: A():n2(0),n1(n2+2){} void Print(){ cout << "n1:" << n1 << ", n2: " << n2 <