十三 java面向对象程序设计(初始化A)
/**
* 初始化(一)
* 成员变量和构造机的初始化过程
* 1,成员变量的初始化:
* 2,构造方法的执行顺序:
* 3,静态成员的执行顺序;
* 4,静态代码块的执行顺序;
*/
/* 一,成员初始化 */
class MemberInitialization
{
/*1,自动初始化*/
private boolean b;
private char c;
private byte by;
private short s;
private int i;
private long l;
private float f;
private double d;
private String str;
private MemberInitialization obj;
public void printInfo1(){
System.out.println(
"boolean " + b + "/n" +
"char " + c + "/n" +
"byte " + by + "/n" +
"short " + s + "/n" +
"int " + i + "/n" +
"long " + l + "/n" +
"float " + f + "/n" +
"double " + d + "/n" +
"String " + str + "/n" +
"reference " + obj
);//类中的成员变量即使没有为他们赋初值,也将会自动初始化.
/*但是在这个方法中定义的变量在使用前没有初始化将提示一个错误.
int i;
i++;
*/
}
/*2,指定初始化*/
//(1),在定义变量的地方初始化.
private boolean bl = true;
private char ch = 'a';
private byte bt = 0;
private short sh = 10;
private int in = 20;
private long lg = 30;
private float fl = 0.0f;
private double dl = 1.0;
private String strg = "string";
private MemberInitialization ob = this;
public void printInfo2()
{
System.out.println(
"boolean " + bl + "/n" +
"char " + ch + "/n" +
"byte " + bt + "/n" +
"short " + sh + "/n" +
"int " + in + "/n" +
"long " + lg + "/n" +
"float " + fl + "/n" +
"double " + dl + "/n" +
"String " + strg + "/n" +
"reference " + ob
);
}
//(2),通过方法初始化
int j = f();
int f(){return 1;}
int x = a();
int y = b();
int a(){return 2;}
int b(){return x*2;}
public static void main(String[] args)
{
new MemberInitialization().printInfo1();
new MemberInitialization().printInfo2();
System.out.println("j = " + new MemberInitialization().j + " " +
"x = " + new MemberInitialization().x + " " +
"y = " + new MemberInitialization().y
);
}
}
/*总结: 类中的成员变量将自动初始化,但是方法中定义的变量必须在使用前初始化*/
/* 输出结果:
boolean false
char
byte 0
short 0
int 0
long 0
float 0.0
double 0.0
String null
reference null
boolean true
char a
byte 0
short 10
int 20
long 30
float 0.0
double 1.0
String string
reference MemberInitialization@190d11
j = 1 x = 2 y = 4
*/
/* 二,构造方机初始化 */
/*1,在构造方法中初始化*/
class Constructor
{
private int i;
public Constructor()
{
i = 10;
//虽然我们在构造方法中将i初始化为10,但是也不能阻止成员变量的自动初始化,
//i初始化过程: 为i自动初始化为0,之后调用构造方法,在将10赋值给成员变量i.
}
public Constructor(int mark){ System.out.println("Constructors(" + mark + ")"); }
}
/*2,初始化的顺序*/
class ConstructorInitialization
{
private Constructor con1 = new Constructor(1);//con1定义在构造方法前
public ConstructorInitialization()
{
System.out.println("ConstructorInitialization()");
con3 = new Constructor(4);
}
private Constructor con2 = new Constructor(2);//con2定义在构造方法后
public void function(){ System.out.println("function()");}
private Constructor con3 = new Constructor(3);//con3定义在成员方法function后
public static void main(String[] args)
{
ConstructorInitialization conIn = new ConstructorInitialization();
conIn.function();
/* 输出的结果为:
* Constructors(1)
* Constructors(2)
* Constructors(3)
* ConstructorInitialization()
* Constructors(4)
* function()
*/
//我们故意颠倒成员定义的顺序,但是通过以上的结果,
//我们得出: 变量定义的先后顺序决定了初始化的顺序,即使变量定义散布于方法之间,
// 他们仍旧会在任何方法(包括构造方法)被调用之前得到初始化.
}
}
/*3,静态数据的初始化*/
class StaticData
{
StaticData(int mark)
{
System.out.println("StaticData(" + mark + ")");
}
}
class StaticTest {
StaticData data4 = new StaticData(4);//data4定义在构造方法前
static StaticData data1 = new StaticData(1);//静态成员data1定义在构造方法前,data4之后
StaticTest()
{
System.out.println("StaticTest()");
StaticData data5 = new StaticData(5);
}
static StaticData data2 = new StaticData(2);//静态成员data2定义在构造方法之后,data4之后
public void function()
{
System.out.println("function()");
}
static StaticData data3 = new StaticData(3);//静态成员data3定义在构造方法,成员方法,data4之后
public static void main(String[] args) {
StaticTest st1 = new StaticTest();//静态对象初始化,此时bow1,bow2,将不会再次初始化.
st1.function();
System.out.println("again...");
StaticTest st2 = new StaticTest();
st2.function();
/* 输出结果:
* StaticData(1)
* StaticData(2)
* StaticData(3)
* StaticData(4)
* StaticTest()
* StaticData(5)
* function()
* again...
* StaticData(4)
* StaticTest()
* StaticData(5)
* function()
*/
//同样,我们颠倒了成员定义的顺序,通过以上输出的结果我们得出:
//静态成员和对象只在第一次该对象被调用时初始化(也就是说在需要时才初始化),并且不会再次被初始化.
//静态成员和对象的初始化是在非静态成员之前初始化的.
}
}
/*4,非静态代码块的初始化*/
class CodeTest
{
{ System.out.println("code1 is calling..."); }//在构造方法之前
CodeTest()
{
System.out.println("CodeTest()");
{ System.out.println("code4 is calling..."); }//在构造方法中
}
{ System.out.println("code2 is calling..."); }//在构造方法后
void function(){ System.out.println("function()"); }
{ System.out.println("code3 is calling..."); }//在成员方法后
public static void main(String[] args)
{
CodeTest ct1 = new CodeTest();
ct1.function();
System.out.println("again...");
CodeTest ct2 = new CodeTest();
ct2.function();
}
/* 输出结果:
* code1 is calling...
* code2 is calling...
* code3 is calling...
* CodeTest()
* code4 is calling...
* function()
* again...
* code1 is calling...
* code2 is calling...
* code3 is calling...
* CodeTest()
* code4 is calling...
* function()
*/
//同样打乱了代码块的顺序,我们得到的结论是:
//代码块是在构造方法之前和成员方法调用前被调用.
}
/*5,静态代码块*/
class StaticCodeTest
{
static{ System.out.println("static code1 is calling..."); }
StaticCodeTest()
{
System.out.println("StaticCodeTest()");
{ System.out.println("static code4 is calling..."); }
}
static { System.out.println("static code2 is calling..."); }
void function(){ System.out.println("function()"); }
static { System.out.println("static code3 is calling..."); }
public static void main(String[] args)
{
StaticCodeTest sct1 = new StaticCodeTest();
sct1.function();
System.out.println("again...");
StaticCodeTest sct2 = new StaticCodeTest();
sct2.function();
}
/* 输出结果:
* static code1 is calling...
* static code2 is calling...
* static code3 is calling...
* StaticCodeTest()
* static code4 is calling...
* function()again...
* StaticCodeTest()
* static code4 is calling...
* function()
*/
//同样,打乱了静态代码块的顺序,我们的结论是:
//同样静态代码块是在构造方法之前和成员方法调用前被调用.但是由于是静态的,所以只被初始化一次.
}
/*6,总结*/
//我们在程序中将所有的成员加进去,看看这个顺序
class SummarizeData
{
SummarizeData(int mark){ System.out.println("SummarizeData(" + mark + ")"); }
}
public class SummarizeTest
{
SummarizeData data4 = new SummarizeData(4);
static SummarizeData data1 = new SummarizeData(1);
{ System.out.println("code1 is calling..."); }
static { System.out.println("static code1 is calling..."); }//在构造方法之前交叉定义
SummarizeTest()
{
System.out.println("SummarizeTest()");
SummarizeData data7 = new SummarizeData(7);
{ System.out.println("code4 is calling..."); }
}
SummarizeData data5 = new SummarizeData(5);
static SummarizeData data2 = new SummarizeData(2);
{ System.out.println("code2 is calling..."); }
static { System.out.println("static code2 is calling..."); }//在构造方法之后交叉定义
void function(){ System.out.println("function()"); }
SummarizeData data6 = new SummarizeData(6);
static SummarizeData data3 = new SummarizeData(3);
{ System.out.println("code3 is calling..."); }
static { System.out.println("static code3 is calling..."); }//在成员方法之后交叉定义
public static void main(String[] args)
{
SummarizeTest st1 = new SummarizeTest();
st1.function();
System.out.println("again...");
SummarizeTest st2 = new SummarizeTest();
st2.function();
}
/* 输出结果:
* SummarizeData(1)
* static code1 is calling...
* SummarizeData(2)
* static code2 is calling...
* SummarizeData(3)
* static code3 is calling...
* SummarizeData(4)
* code1 is calling...
* SummarizeData(5)
* code2 is calling...
* SummarizeData(6)
* code3 is calling...
* SummarizeTest()
* SummarizeData(7)
* code4 is calling...
* function()
* again...
* SummarizeData(4)
* code1 is calling...
* SummarizeData(5)
* code2 is calling...
* SummarizeData(6)
* code3 is calling...
* SummarizeTest()
* SummarizeData(7)
* code4 is calling...
* function()
*/
}
/* 通过以上实例我们得出的结论:
* 程序的执行顺序是:
* 首先执行静态成员和静态代码块(静态成员变量和静态代码块按照先后定义的顺序执行,并且只执行一次)
* 之后执行成员变量和非静态代码块(同样,成员变量和非静态代码块按照定义的先后顺序执行,并且可以执行多次)
* 在次执行构造方法
* 最后执行成员方法
*/