• 静态语句块,实例语句块,构造函数的初始化顺序


    一,静态语句块的定义

             在一个类中,不属于任何方法体并且以static关键字修饰的语句块,称为静态语句块。

          因为静态语句块常用来进行类变量的初始化,所以也称为静态初始化程序块。

         格式:static{   };

      ♦静态语句块在加载该类时执行一次(此处的类加载是在该类被调用时才进行加载,比如:当要验证的语句和main()方法在一个类中时,此时调用main()方法时,要先对该类进行加载才能调用main()方法,但是若main()方法和要验证的语句不在一个类中时,则先进行main()方法的类的加载和main()方法的调用,然后当后面要调用放了要验证的语句的类时(即new该类对象时),验证类才会被加载)如果一个类中定义了多个静态语句块,则这些语句块将按在类中出现的先后次序运行。

      二, 程序初始化的优先级:  基类>派生类

                        static>实例块

                  即:先执行基类中的static,在执行派生类中的static,在执行基类中的实例块,在执行派生类中的实例块。

                              ♦(前两种static,谁在前,先打印谁)

                             1.private static int i;         //静态变量

                            2.static{    i=5    };            //静态语句块

                          3. public static int a(){       //静态方法

                                    };

                       ♦ 静态语句块,静态变量在类加载时运行,静态方法在手动调用时才执行。

                       ♦实例块包括:  int  i=0;    {    };(这两个按先后次序执行)

                               构造函数 (一般最后执行)

                       ♦实例块只有在新new对象后,才执行。

    三,代码实现 -1:

     1 public class ObjectInitTest {
     2     {
     3         System.out.println("实例块a");
     4     }
     5     static{
     6         System.out.println("b");
     7     }
     8 
     9     private  int a= methoda();
    10     private static int b=methodb();
    11     private static int c=4;
    12 
    13     private static  int  methodb() {
    14         System.out.println("静态属性b");
    15         System.out.println(b);
    16         return 9;
    17     }
    18     private  int  methoda() {
    19         System.out.println("属性a");
    20         return 8;
    21     }
    22     private static  void  methodc() {
    23         System.out.println("静态属性c");
    24     }
    25 
    26 
    27     public ObjectInitTest(int a,int b) {
    28         this.a=a;
    29         this.b=b;
    30     }
    31 
    32     {
    33             System.out.println("实例块b");
    34             System.out.println(a);
    35     }
    36 
    37     public static void main(String[] args) {
    38 
    39          ObjectInitTest o=new ObjectInitTest(1,2);
    40         //System.out.println(a);  //直接调用a和methoda()会出错,因为静态方法不能直接访问所属类的非静态变量和方法
    41         //System.out.println(o.methodc());
    42         System.out.println(o.methoda());
    System.out.println(o.a);  //非静态变量和方法的访问,需要通过对象
    43 System.out.println(b); //此处b为静态变量,可在main的静态方法中直接访问 44 } 45 }

                   

        运行结果及分析

          

            分析:

         

     应注意问题:

             1,  因为静态方法的调用不是通过实例对象进行的,静态方法是类级别的,所以在静态

       方法中没有this指针,且不能直接访问所属类的非静态变量和方法,只能访问方法内定义的

       局部变量,自己的参数和静态变量。非静态变量和方法的访问,需要通过对象。

             2,main()方法是一个静态方法。如果要在main()方法中访问所在类的成员变量或方法,就必须首先创建相应

       的实例对象。否则只能访问静态方法或变量。

              3,static变量只能用static方法给其赋值,但普通变量随意。

     三,代码实现-2

     1 package L13;
     2 class A{    //父类
     3     protected   int a;
     4     protected   int c;
     5 
     6     public A(int a){
     7         this.a=a;
     8         this.c=1;
     9         System.out.println("父类构造函数");
    10     }
    11     static{   //静态语句块
    12         System.out.println("父类静态语句块");
    13 
    14     }
    15     {
    16         System.out.println("父类实例语句块");
    17     }
    18     public void show(){
    19         System.out.println("父类方法");
    20         System.out.println("a:"+a);
    21     }
    22     public void show1(){
    23         System.out.println("父类独有的方法");
    24     }
    25 }
    26 /**
    27  * 派生类B有两部分
    28  *      1.从基类继承来的成员(可重新初始化)
    29  *      2.自己定义的成员
    30  *
    31  *      super和this都必须写在第一行
    32  *      super();   //在派生类中调用基类构造函数,在派生类方法中必须写在首行
    33  *      super.方法名();//在派生类中,当继承下来的基类方法被派生类重写,在派生类中可用super.方法名()来调用基类的方法。
    34  */
    35 class B extends A{    //B继承A类
    36     private int a;
    37     private int b;
    38     public B(){
    39         super(3);   //调用父类的构造方法
    40         this.a=2;
    41         this.b=2;
    42         System.out.println("子类构造函数");
    43     }
    44     static{   //静态语句块
    45         System.out.println("子类静态语句块");
    46 
    47     }
    48     {
    49         System.out.println("子类实例语句块");
    50     }
    51     public void show(){
    52         System.out.println("子类方法");
    53         System.out.println("a:"+a);            //当父类和子类拥有相同变量时,若直接用a 打印的是子类中的a变量的值
    54         System.out.println("a:"+super.a);     //若用super.a调用,当在子类中没有对其进行初始化,则打印的就是父类中变量a的值。
    55                                                 //若以初始化,则打印的是初始化后的。
    56         System.out.println("c:"+c);            //但子类中没有与父类重复的变量,可直接用c打印变量值。
    57     }
    58     public void test(){
    59         super.show();   //  与变量类似,对于被子类重写了的方法,需用super.方法名()来掉用
    60         this.show1();   //对于父类独有的,直接掉用。
    61         this.show();
    62     }
    63 }
    64 public class DeriveTest {
    65     public static void main(String[] args) {
    66         B b=new B();
    67         //b.show();    //因为子类方法名与父类相同,且返回值与参数列表也相同,所以被B继承的父类的show()方法已被子类相同方法重写
    68                      //所以b.show()打印出来就是子类中show()方法的内容。
    69         //b.show1();   //但对于父类独有的方法,当被B类继承下来后,因为没有被重写,所以 b.show1();打印出来的就是父类中方法的内容。
    70        // b.test();
    71         B c=new B();
    72     }
    73 
    74 }

      运行结果:

     需注意:

     *          this关键字的两个用法:

     *             1.在构造函数中调用待传入int参数的其它的构造函数,如this( )。

     *        2.在成员方法里面访问其它成员(变量,方法),前面可以添加this.变量/方法。

     *

     *    super关键字的三个用法:

     *       1.在派生类的构造函数中调用基类的带int参数的构造函数 如super( )。

     *       2.super.func() 在派生类中,调用从基类继承来的func方法

     *       3.super.a 在派生类中,调用从基类继承来的名字叫a的成员变量

                             super关键字

              在对象的内部使用,可以代表父类对象

              1,访问父类的属性 super.age

              2,访问父类的方法 super.eat()

              3,子类的构造过程中必须调用其父类的构造方法 super();

                   ( 如果子类的构造方法中没有显式调用父类的构造方法,则系统默认调用父类无参的构造方法

                        如果显式的调用构造方法,必须在子类构造方法的第1行

                        如果子类构造方法中既没有显示调用父类的构造方法,而父类有没有无参的构造方法,则编译出错。)

             this和super关键字都和对象有关,所以在static方法中不能使用这两个关键字

              

      

  • 相关阅读:
    todo-list
    codeforces 794 (#414 DIV1+DIV2)
    2018bnu校赛总结
    codeforces 743D
    HDU-2196 Computer (树形DP)
    HDU- 1005 Number Sequence(矩阵快速幂)
    HDU- 4000 Fruit Ninja(树状数组)
    codeforces 505C
    codeforces 286B
    codeforces 3D
  • 原文地址:https://www.cnblogs.com/ljl150/p/11652035.html
Copyright © 2020-2023  润新知