【校招VIP】java 初始化总结

08月04日 收藏 0 评论 0 java开发

【校招VIP】java 初始化总结

转载声明:文章来源https://blog.csdn.net/yangyan19870319/article/details/6202403

相信好多人对java初始化问题一直存有疑惑,下面是我看到的比较详细的java初始化问题讲解

一 java初始化基础知识

1、 一个类的所有基本类型数据成员都会保证获得一个初始值。 

非基本类型,会初始化为null

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class Initialization { 
int a; 
char b; 
short s; 
float f; 
long lo; 
double dou; 
byte e; 
boolean flag; 
       Object obj; 
   
public static void main(String [] args){ 
    Initialization init = new Initialization(); 
    init.print(); 
   
public void print(){ 
    System.out.println("int a="+a+"/nchar b="+b+" /n"+" short s="+s+"/n float f="+f+"/n long lo="+lo+"/n double dou="+dou+"/n byte e="+e+"/n boolean flag="+flag+"/n Object obj="+obj); 
}

出来结果为

1
2
3
4
5
6
7
8
9
int a=0 
char b= 
short s=0 
float f=0.0 
long lo=0 
double dou=0.0 
byte e=0 
boolean flag=false 
Object obj=null

可见,java会为类的基本类型的变量提供一个初始值,各类型初始值不同,非基本类型初始为null。注意,这里的变量必须是类变量,注意,只会为类变量提供初始化,而局部变量不会。如果局部变量没有初始化,会收到一个出错信息 

2、可以通过构造方法或其他方法进行初始化,但是不会妨碍java默认的初始化

看下面的例子 

1
2
3
4
5
6
7
8
9
10
11
12
int i; 
       Object obj; 
public Initialization(){ 
    System.out.println("before i="+i+"  obj="+obj); 
    i = 1; 
    obj = new Object(); 
    System.out.println("after i="+i+" obj="+obj); 
   
public static void main(String [] args){ 
    Initialization init = new Initialization(); 
}

输出结果为

1
2
before i=0  obj=null 
after i=1 obj=java.lang.Object@de6ced

由此可见,不论是基本类型,还是其他的类。java默认的初始化是最先发生的,位于一切方法之前。 

3、static 数据的初始化 

static 数据会发生上述同样的事情(基本类型,获得对应基本类型的初始化值;非基本类型,初始化为null)
但是,由于static值只有一个存储区域,所以static值只会被初始化一次,看下面的例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public static void main(String [] args){ 
Cupboard cup = new Cupboard(); 
cup = new Cupboard(); 
    
      
    public class Cupboard { 
static Bowl bowl = new Bowl(); 
   
public Cupboard(){ 
    System.out.println("initialization Cupboard"); 
    
    public class Bowl { 
public Bowl(){ 
    System.out.println("init ing Bowl~"); 
    }

输出结果如下

1
2
3
init ing Bowl~ 
initialization Cupboard 
initialization Cupboard

所以说,static数据只会在第一次进行初始化,之后就不会了。 

4、初始化顺序

在一个类中,无论变量的定义是在方法之前还是方法之后,都会在方法之前进行初始化的; 另外,static数据初始化位于非static数据初始化之前
来看下边的例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public static void main(String [] args){ 
Cupboard cup = new Cupboard(); 
   
  
  public class Cupboard { 
Pan pan = new Pan(); 
public Cupboard(){ 
    System.out.println("initialization Cupboard"); 
static Bowl bowl = new Bowl(); 
  
  public class Bowl { 
public Bowl(){ 
    System.out.println("init ing Bowl~"); 
  
  public class Pan { 
public Pan(){ 
    System.out.println("initialization Pan"); 
  }

结果如下

1
2
3
init ing Bowl~ 
initialization Pan 
initialization Cupboard

5、静态块 

静态块里的变量初始化顺序位于普通变量之前,和static变量相比,则是完全由定义的顺序来决定了。另外,静态块里的变量也是只初始化一次,这点和static变量一致。示例如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class Other { 
static{ 
    Bowl bowl2 = new Bowl(2); 
static Bowl bowl = new Bowl(1); 
   
private Bowl bowl3 = new Bowl(3); 
   
public static void main(String [] args){ 
    Other other = new Other(); 
    other = new Other(); 
    
    public class Bowl { 
public Bowl(){ 
    System.out.println("init ing Bowl~"); 
   
public Bowl(int i){ 
    System.out.println("init ing Bowl"+i); 
    }

输出结果为

1
2
3
4
init ing Bowl2 
init ing Bowl1 
init ing Bowl3 
init ing Bowl3

如果调换static变量和静态块的位置,输出结果如下 

1
2
3
4
init ing Bowl1 
init ing Bowl2 
init ing Bowl3 
init ing Bowl3

6、涉及到继承时 初始化顺序 

初始化时,如果有static变量或静态块,其初始化顺序是位于最前面的,无论变量位于子类还是父类中,它们二者之间的顺序,可参见第5点; static变量初始完了后,先初始化父类,然后是子类。
示例如下 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public class Base { 
Bowl bowl = new Bowl(1); 
public Base(){ 
    System.out.println("initialization Class Base"); 
static Bowl bowl5 = new Bowl(5); 
static{ 
    Bowl bowl6 = new Bowl(6); 
    
    public class Sub extends Base { 
Bowl bow2 = new Bowl(2); 
public Sub(){ 
    System.out.println("initialize Sub"); 
static Bowl bowl3 = new Bowl(3); 
   
static{ 
    Bowl bowl4 = new Bowl(4); 
    
    public class Test { 
public static void main(String []args){ 
    Sub sub = new Sub(); 
    }

输出结果如下

1
2
3
4
5
6
7
8
init ing Bowl5 
init ing Bowl6 
init ing Bowl3 
init ing Bowl4 
init ing Bowl1 
initialization Class Base 
init ing Bowl2 
initialize Sub

二 问题举例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package test;
class Singleton { 
private static Singleton obj = new Singleton();  
public static int counter1; 
public static int counter2 = 0; 
private Singleton() {    
counter1++;   
counter2++;    
public static Singleton getInstance() { 
return obj; 
}   
public class MyMain { 
public static void main(String[] args) { 
Singleton obj = Singleton.getInstance(); 
System.out.println("obj.counter1=="+obj.counter1); 
System.out.println("obj.counter2=="+obj.counter2); 
}

 这段程序代码输出,实际运行结果:
obj.counter1==1
obj.counter2==0

相信大家跟我一样会对这个结果存有疑问,这段代码中尤其注意:private static Singleton obj = new Singleton(); 在类Singleton中的位置,改变位置会有不同结果。关于这段代码运行结果的解释:
当程序执行private static Singleton obj = new Singleton(); 句的时候就去调用了Singleton构造器,此时counter1、counter2都是1,但是接着执行向下执行:public static int counter1;时将1赋给counter1,执行public static int counter2 = 0;时重新给counter2赋值为0

三 典型初始化例子

Java初始话很好的一个例子, 摘自Think in Java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
package cn.edu.xupt.test; 
   
//: initialization/StaticInitialization.java 
//Specifying initial values in a class definition. 
   
//无论创建多少对象, 静态数据都只占用一份存储区域 
//初始化的顺序是先静态对象(如果它们尚未因前面的对象创建过程而被初始化), 而后是"非静态"对象 
//载入.class文件(这将创建Class对象),有关静态初始化的所有动作执行. 
//静态初始化只在Class对象首次加载的时候进行一次 
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()"); 
        bowl2.f1(1); 
    
   
    void f2(int marker) { 
        System.out.println("f2(" + marker + ")"); 
    
   
    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 marker) { 
        System.out.println("f3(" + marker + ")"); 
    
   
    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)
 */// :~
C 0条回复 评论

帖子还没人回复快来抢沙发