#java 静态成员初始化
一、显式静态成员初始化
静态成员初始化可以一起被初始化,但只能被初始化一次,即静态成员的初始化不一定是在第一次创建实例对象时被初始化,也可以是在第一访问静态成员时初始化。所谓显式的静态成员初始化指的是将静态成员用一个大括号写到一起,并且前面用static关键字。例如:
static Cup cup1;
static Cup cup2;
static {
cup1 = new Cup(1);
cup2 = new Cup(2);
}
创建静态对象放在一起,当访问时就一起被创建并被初始化。这种写法java并不常见,但java支持这种写法。
例子如下
先看代码:
package java初始化;
public class ExlicitStatic {
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println("Inside main()");
Cups.cup1.f(99);
Cups.cup2.f(88);
}
}
class Cup{
Cup(int marker){
System.out.println("Cup("+marker+")");
}
void f(int marker) {
System.out.println("f("+marker+")");
}
}
class Cups{
static Cup cup1;
static Cup cup2;
static {
cup1 = new Cup(1);
cup2 = new Cup(2);
}
Cups(){
System.out.println("Cups()");
}
}
代码运行结果为:
分析
此处可以看到并不是非要创建实例对象时才会初始化静态成员,当第一次访问到静态成员时静态成员会被初始化。整个代码运行过程是先从程序入口,打印第一行输出Inside main,之后执行第二行Cups.cup1.f(99);但Cups中有静态成员,因此先初始化静态成员,之后输出两个Cup(1)和Cup(2),然后输出f(99)的打印。最后执行第三行Cups.cup2.f(88);,由于先前静态成员已经被初始化化,因此此处不再进行初始化,只执行构造器初始化,打印出f(88)。
二、实例成员初始化
根据前面所讲,静态成员变量可以一起被初始化,因此实例成员变量也可以被一起被初始化,方法是将其全部放入一个大括号内,与显式静态不同的是,实例成员变量大括号前面不写任何关键字,除此,内部除了实例变量,还可以写其他语句。
例子如下
同样直接将测试代码给出:
package java初始化;
public class Mugs {
Mug mug1;
Mug mug2;
{
mug1 = new Mug(1);
mug2 = new Mug(2);
System.out.println("mug1 and mug2 initialized");
}
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println("Inside Main()");
new Mugs();
System.out.println("new Mugs() completed");
new Mugs(1);
System.out.println("new Mugs(1) completed");
}
public Mugs() {
System.out.println("Mug()");
}
public Mugs(int i) {
System.out.println("Mug(int)");
}
}
class Mug{
Mug(int marker){
System.out.println("Mug("+marker+")");
}
void f(int marker) {
System.out.println("marker("+marker+")");
}
}
本例输出结果是:
分析
本例子主要是对实例对象初始化的测试,可以从程序运行结果看出,当每次一实例对象被创建时,实例对象都会被初始化一次,这就是两种的不同。
三、java成员初始化
当一个程序类中既有实例变量,又有静态变量时,首先初始化静态变量,之后初始化实例变量。并且静态变量只在第一次被访问或者对象第一次被创建时才会被初始化且只被初始化一次。静态变量之间的初始化顺序按照代码顺序进行初始化,之后才是实例变量的初始化,且能被多次初始化。
例子如下
先看代码,代码后面标注的数字即为在初始化过程中程序执行的顺序,并且输出顺序也是如此。
package java初始化;
public class StaticInitialization {
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println("Creating new Cupboard() in main()");//10
new Cupboard();
System.out.println("Creating new Cupboard() in main()");//14
new Cupboard();
table.f2(1);//18
cupboard.f3(1);//19
}
static Table table =new Table();//1
static Cupboard cupboard = new Cupboard();
}
class Bowl{
Bowl(int marker){
System.out.println("Bow1("+marker+")");
}
void f1(int marker) {
System.out.println("f1("+marker+")");//4
}
}
class Table{
static Bowl bowl1 = new Bowl(1);//1
Table(){
System.out.println("Table()");//3
bowl2.f1(1);//4
}
void f2(int marker) {
System.out.println("f2("+marker+")");
}
static Bowl bowl2 = new Bowl(2);//2
}
class Cupboard{
Bowl bowl3 = new Bowl(3);//7 ----11 -----15
static Bowl bowl4 = new Bowl(4);//5
Cupboard(){
System.out.println("Cupboard()");//8 ----12 -----16
bowl4.f1(2);//9 -----13 ----17
}
void f3(int marker) {
System.out.println("f3("+marker+")");
}
static Bowl bowl5 = new Bowl(5);//6
}
结果显示:
分析
从本例中可以看出了Java静态成员和实例成员初始化过程,对于在平时学习中很好的理解Java有帮助。不在讲述代码,可以通过注释顺序和结果顺序来理解代码,代码也比较简单。
总结
java 构造器初始化//
8种基本数据成员如果没有初始化,则Java会自动进行初始化,例如引用型的初始化为NULL,int 、short、long、byte初始化为0,double、char初始化为0.0,boolean初始化为false。
静态数据成员初始化// 静态成员先初始化、再初始化实例成员,静态成员的实例化之间顺序按代码顺序实例化,静态成员只在第一次创建时优先实例化,后面不在进行实例化,即只在类当中只实例化一次。