zoukankan      html  css  js  c++  java
  • 阿里面试题:关于类中静态,非静态,构造方法的执行顺序

    可见Java基础还是很重要的,我 相信还是有很多人写错的,贴出来大家一起学习。

    题目要求:输出运行结果:

    [java] view plain copy
     
    1. public class Text {  
    2.     public static int k =0 ;  
    3.     public static Text t1 = new Text("t1") ;  
    4.     public static Text t2 = new Text("t2") ;  
    5.     public static int i = print("i") ;  
    6.     public static int n =99 ;  
    7.     public int j = print("j") ;  
    8.     {  
    9.         print("构造块");  
    10.     }  
    11.     static {  
    12.         print("静态块");  
    13.     }  
    14.     public Text(String str){  
    15.         System.out.println((++k)+":"+str+"   i="+i+"    n="+n) ;  
    16.         ++i;++n ;  
    17.     }  
    18.     public static int print(String str){  
    19.         System.out.println((++k)+":"+str+"   i="+i+"    n="+n) ;  
    20.         ++n;  
    21.         return ++i ;  
    22.     }  
    23.     public static void main (String args[]){  
    24.          Text t = new Text("init") ;  
    25.     }  
    26. }  

    运行结果如下:

    1:j   i=0    n=0

    2:构造块   i=1    n=1

    3:t1   i=2    n=2

    4:j   i=3    n=3

    5:构造块   i=4    n=4

    6:t2   i=5    n=5

    7:i   i=6    n=6

    8:静态块   i=7    n=99

    9:j   i=8    n=100

    10:构造块   i=9    n=101

    11:init   i=10    n=102

     

    首先看到static关键字,脑子里面第一反应有几点,

    1、公有属性,可以有类名称直接访问。

    2、静态方法,可以有类名称直接方法。

    3、静态方法或者属性,可以再对象实例化之前就调用

    至于该题中,顺序执行,先执行public static int k =0 ;

    因为没有输出不用考虑这个,接着public static Text t1 = new Text("t1") ;

    在t1对象初始化时先执行非静态方法或者非静态常量,顺序执行,接着运行构造参数,

    根据程序来看应该打印三条记录,分别是

    1:j   i=0    n=0

    2:构造块   i=1    n=1

    3:t1   i=2    n=2

    接下来public static Text t2 = new Text("t2") ;同理,执行完之后继续执行static代码块或者赋值静态变量,在main()方法中new了一个新的实例,静态变量只执行一次,接下来就是顺序执行非静态方法---->构造方法。应该是这样的顺序,面试的时候我写的不完成,哎。

    接着想到继承关系(extends)子类继承一个父类之后,对象初始化的顺序又是怎样?

    我写了一个demo,大家共勉

     

    [java] view plain copy
     
    1. class A{  
    2.     public static int k = 0 ;  
    3.     static {  
    4.         System.out.println("父类静态方法") ;  
    5.     }  
    6.     {  
    7.         System.out.println("父类非静态方法") ;  
    8.     }  
    9.     public A(){  //构造  
    10.         System.out.println("父类构造");  
    11.     }  
    12. }  
    13. class B extends A{  
    14.     static {  
    15.         System.out.println("子类静态方法") ;  
    16.     }  
    17.     {  
    18.         System.out.println("子类非静态方法") ;  
    19.     }  
    20.     public B(){  //构造  
    21.         System.out.println("子类构造");  
    22.     }  
    23. }  
    24. public class Demo {  
    25.     public static void main(String args[]){  
    26.         B b = new B() ;  
    27.     }  
    28. }  

     

    输入结果如下:

    父类静态方法

    子类静态方法

    父类非静态方法

    父类构造

    子类非静态方法

    子类构造

     

    最后总结了几点:

    [java] view plain copy
     
    1. 1 /*   
    2.   
    3. 2          * 几大原则   
    4.   
    5. 3          * 一、静态成员变量(Static)   
    6.   
    7. 4          *  1、静态成员变量为类变量,所有对象共享同一内存空间   
    8.   
    9. 5          *  2、静态成员变量的声明和定义仅在首次加载类时执行一次   
    10.   
    11. 6          *  3、首次加载类时首先对所有静态成员变量根据类型默认赋初值,然后再对有右值的附右值   
    12.   
    13. 7          * 二、静态初始块   
    14.   
    15. 8          *  1、静态初始化块仅在首次加载类时执行一次   
    16.   
    17. 9          * ······多个静态成员变量与静态始化快参照出现顺序先后执行······   
    18.   
    19. 10          * 三、动态成员变量   
    20.   
    21. 11          *  1、动态成员变量定义在每次实例化对象时在构造函数之前执行   
    22.   
    23. 12          * 四、动态初始化块   
    24.   
    25. 13          *  1、动态初始化块在每次实例化对象时在构造函数之前执行   
    26.   
    27. 14          * ······多个动态成员变量与动态初始化块参照出现顺序先后执行······   
    28.   
    29. 15          * 总结:总的来说,在不涉及继承的前提下,当首次加载类时,按照如下顺序执行   
    30.   
    31. 16          *  1、按照出现顺序先后执行静态成员变量定义与静态初始化块   
    32.   
    33. 17          *  2、按照出现顺序先后执行动态成员变量定义与动态初始化块   
    34.   
    35. 18          *  3、执行构造函数   
    36.   
    37. 19          *  再次实例化对象时只执行第2、3步即可   
    38.   
    39. 20          *    
    40.   
    41. 21          * ············成员变量与定义与初始化块先于构造函数执行·········   
    42.   
    43. 22          * 五、当涉及到继承时,按照如下顺序执行   
    44.   
    45. 23          *  1、执行父类的静态成员变量定义与静态初始化块,执行子类的静态成员变量定义与静态初始化块   
    46.   
    47. 24          *  2、执行父类的非静态成员变量定义与动态初始化块,执行父类构造方法   
    48.   
    49. 25          *  3、执行子类的非静态成员变量定义与动态初始化块,执行子类构造方法   
    50.   
    51. 26          * 另:父类构造方法中用到的方法如果已被子类重写,那么在构造子类对象时在调用父类构造函数中使用子类重写的方法  

    public class DateTest {

      public static void main(String[] args) {
        new DateTest(); //4.第四步,new一个类,但在new之前要处理匿名代码块
      }

      static int num = 4; //2.第二步,静态变量和静态代码块的加载顺序由编写先后决定

      DateTest() { // 类的构造函数,第四个加载
        System.out.println("d"); //8.第八步,最后加载构造函数,完成对象的建立
      }
      {
        num += 3;
        System.out.println("b"); //5.第五步,按照顺序加载匿名代码块,代码块中有打印
      }

      int a = 5; //6.第六步,按照顺序加载变量

      { // 成员变量第三个
        System.out.println("c");
        System.out.println(a);//7.第七步,按照顺序打印c
      }


      static { // 3.第三步,静态块,然后执行静态代码块,因为有输出,故打印a
        System.out.println("a");
      }

      static void run() // 静态方法,调用的时候才加载// 注意看,e没有加载
      {
        System.out.println("e");
      }

    }

  • 相关阅读:
    检查IP地址是否有效(delphi)
    Oracle 常用操作
    DBGrid中顯示行號的終極解決方案(Delphi篇)
    从零开始学Java 第24章 网络聊天室
    JavaScript的循环结构和经典题目
    html5/css3布局(一)
    html常用的基本标签
    HTML5——css基础语法
    JavaScript函数使用和DOM节点
    C语言Ⅰ|博客作业07
  • 原文地址:https://www.cnblogs.com/smallFishs/p/6185619.html
Copyright © 2011-2022 走看看