一、类的成员

  1、属性:成员变量

  2、方法:成员方法

  3、构造器:构造方法

  4、代码块:初始化块

  5、内部类

二、非静态代码块

  1、非静态代码块格式

【修饰符】 class 类名{
 	{
 	  非静态代码块;
 	}
 }

  

  2、非静态代码中的代码执行时机

    (1)在“每次”创建对象的时候执行;

    (2)比构造器要早;

三、实例初始化

  1、实例初始化是什么?

    实例初始化过程:每次创建对象时,为对象进行初始化的操作

  2、对象的初始化有那几部分组成?

    (1)成员变量显示赋值;

    (2)执行非静态代码块;

    (3)执行构造器;

  3、实例初始化是怎样的?

    Java 编译器其实,会把上面三个部分的代码,合成一个叫做 <init>(【形参列表】)实例初始化方法。

    即 编译后的 .class 字节码信息中,是没有构造器这个概念的。

    <init>(【形参列表】) 实例初始化方法的代码就是由三个部分组成的:

    (1)成员变量显示赋值的代码;

    (2)非静态代码块中的代码;

    (3)构造器中的代码;

     注意:

      ① 其中(1)和(2)将会按照先后顺序执行,而构造器一定是它们当中的最后执行。

      ② 而且,有几个构造器,就会有几个实例初始化方法。那么当我们创建对象的时候,调用对应的构造器时,其实执行的是对应的实例初始化方法<init>(【...】)

  4、

四、案例

  1、案例一

 1 public class TestInit {
 2     public static void main(String[] args) {
 3         MyClass my1 = new MyClass();//调用无参构造
 4         MyClass my2 = new MyClass("test");//调用有参构造
 5     
 6         System.out.println("-----------------");
 7         
 8         Demo d1 = new Demo();//调用无参构造,本质上是调用<init>()实例初始化方法
 9         Demo d2 = new Demo("test");//调用有参构造,本质上是调用<init>(形参列表)实例初始化方法
10     }
11 }
12 class MyClass{
13     private String str = "hello";//显式赋值
14     
15     public MyClass(){
16         System.out.println("无参构造");
17     }
18     public MyClass(String str){
19         this.str = str;
20         System.out.println("有参构造");
21     }
22     
23     {
24         System.out.println("非静态代码块");
25     }
26 }
27 
28 class Demo{
29     {
30         System.out.println("非静态代码块1");
31     }
32     
33     private String str = assign();//调用方法,来为str进行显式赋值
34     
35     public Demo(){
36         System.out.println("无参构造");
37     }
38     public Demo(String str){
39         this.str = str;
40         System.out.println("有参构造");
41     }
42     
43     {
44         System.out.println("非静态代码块2");
45     }
46     
47     public String assign(){
48         System.out.println("assign方法");
49         return "hello";
50     }
51 }
52 
53 //运行结果
54 非静态代码块
55 无参构造
56 非静态代码块
57 有参构造
58 -----------------
59 非静态代码块1
60 assign方法
61 非静态代码块2
62 无参构造
63 非静态代码块1
64 assign方法
65 非静态代码块2
66 有参构造

   

 

  2、案例二

 1 public class TestInit {
 2     public static void main(String[] args) {
 3         /*
 4         Father f = new Father();
 5         //父类的无参构造
 6         */
 7         
 8         /*
 9          * Son s = new Son();
10          * 父类的无参构造
11             子类的无参构造
12          */
13         
14         //Son s2 = new Son("test");
15         /*
16          * 父类的无参构造
17         子类的有参构造
18          */
19         
20         Son s3 = new Son("test", 10);
21         /*
22          * 父类的无参构造
23             子类的有参构造1
24             子类的有参构造2
25          */
26     }
27 }
28 class Father{
29     public Father(){
30         System.out.println("父类的无参构造");
31     }
32 }
33 class Son extends Father{
34     private String str;
35     private int num;
36     
37     public Son(){
38         //隐含了super();  子类的构造器中一定会调用父类的构造器,默认调用父类的无参构造
39         System.out.println("子类的无参构造");
40     }
41     
42     public Son(String str){
43         //隐含了super()
44         this.str = str;
45         System.out.println("子类的有参构造1");
46     }
47     
48     public Son(String str,int num){
49         this(str);
50         this.num = num;
51         System.out.println("子类的有参构造2");
52     }
53 }
54 
55 //运行结果
56 父类的无参构造
57 子类的有参构造1
58 子类的有参构造2

 

  3、案例三

 1 /*  父子类的实例初始化过程:
 2  * (1)先执行父类的实例初始化方法
 3  *   它由三部分:
 4  *     ①成员变量的显式赋值
 5  *     ②非静态代码块
 6  *     ③构造器
 7  * (2)再执行子类的实例初始化方法
 8  *   它由三部分:
 9  *     ①成员变量的显式赋值
10  *     ②非静态代码块
11  *     ③构造器
12  * 
13  * super()或super(实参列表)之前说的是调用父类的构造器,其实是调用父类对应的实例初始化方法
14  * super()或super(实例列表)之前说的是在子类构造器的首行,其实是在子类实例初始化方法的首行
15  */
16 public class TestInit2 {
17     public static void main(String[] args) {
18         Zi z = new Zi();//312645
19     }
20 }
21 class Fu{
22     private String strFu = assignFu();
23     {
24         System.out.println("(1)父类的非静态代码块");
25     }
26     public Fu(){
27         System.out.println("(2)父类的无参构造");
28     }
29     public String assignFu(){
30         System.out.println("(3)父类的assignFu()");
31         return "fu";
32     }
33 }
34 class Zi extends Fu{
35     private String strZi = assignZi();
36     {
37         System.out.println("(4)子类的非静态代码块");
38     }
39     public Zi(){
40         //super()  ==>调用父类的实例初始化方法,而且它在子类实例初始化方法的首行
41         System.out.println("(5)子类的无参构造");
42     }
43     
44     public  String assignZi(){
45         System.out.println("(6)子类的assignZi()");
46         return "zi";
47     }
48 }
49 
50 //运行结果
51 (3)父类的assignFu()
52 (1)父类的非静态代码块
53 (2)父类的无参构造
54 (6)子类的assignZi()
55 (4)子类的非静态代码块
56 (5)子类的无参构造

 

  4、案例四

 1 public class TestInit3 {
 2     public static void main(String[] args) {
 3         Er r = new Er();//612645,因为子类重写了assign()
 4         
 5 //      Ba b = new Ba();
 6     }
 7 }
 8 class Ba{
 9     private String str = assign();
10     {
11         System.out.println("(1)父类的非静态代码块");
12     }
13     public Ba(){
14         System.out.println("(2)父类的无参构造");
15     }
16     public String assign(){
17         System.out.println("(3)父类的assign()");
18         return "ba";
19     }
20 }
21 class Er extends Ba{
22     private String str = assign();
23     {
24         System.out.println("(4)子类的非静态代码块");
25     }
26     public Er(){
27         //super()  ==>调用父类的实例初始化方法,而且它在子类实例初始化方法的首行
28         System.out.println("(5)子类的无参构造");
29     }
30     
31     public String assign(){
32         System.out.println("(6)子类的assign()");
33         return "er";
34     }
35 }
36 
37 
38 //运行结果
39 (6)子类的assign()
40 (1)父类的非静态代码块
41 (2)父类的无参构造
42 (6)子类的assign()
43 (4)子类的非静态代码块
44 (5)子类的无参构造

 

 

 

六、总结

  实例初始化过程:
    实例初始化方法就是执行类的 <init>() 方法:
  • <init>() 方法可能重载有多个,有几个构造器就有几个 <init>方法;
  • <init>() 方法由非静态实例变量显示赋值代码和非静态代码块、对应构造器代码组成;
  • 非静态实例变量显示赋值代码和非静态代码块从上到下顺序执行,而对应构造器的代码最后执行;
  • 每次创建实例对象,调用对应构造器,执行的就是对应的<init>方法;
  • <init> 方法的首行是 super() 或 super(实参列表),即对应父类的 <init>() 方法;
 

 

posted on 2020-11-15 22:35  格物致知_Tony  阅读(397)  评论(0编辑  收藏  举报