zoukankan      html  css  js  c++  java
  • JAVA程序执行顺序(静态代码块》非静态代码块》静态方法》构造函数)

    总结:静态代码块总是最先执行。

              非静态代码块跟非静态方法一样,跟对象有关。只不过非静态代码块在构造函数之前执行。

              父类非静态代码块、构造函数执行完毕后(相当于父类对象初始化完成), 才开始执行子类的非静态代码块和构造函数。

    ================================================================================

    相同点:都是在JVM加载类时且在构造方法执行之前执行,在类中都可以定义多个,

        一般在代码块中对一些static变量进行赋值。

    不同点:静态代码块在非静态代码块之前执行

    (静态代码块—>非静态代码块—>构造方法)。

        静态代码块只在第一次被类加载器加载时执行一次,之后不再执行,而非静态代码块在每new一次就执行一次。非静态代码块可在普通方法中定义(不过作用不大);而静态代码块不行。

    JVM加载类时会执行这些静态的代码块,如果static代码块有多个,JVM将按照它们在类中出现的先后顺序依次执行它们,每个代码块只会被执行一次。

    例子一:

    1. public class PuTong {
    2. public PuTong(){
    3. System.out.print("默认构造方法!-->");
    4. }
    5.  
    6. //非静态代码块
    7. {
    8. System.out.print("非静态代码块!-->");
    9. }
    10.  
    11. //静态代码块
    12. static{
    13. System.out.print("静态代码块!-->");
    14. }
    15.  
    16. public static void test(){
    17. {
    18. System.out.println("普通方法中的代码块!");
    19. }
    20. }
    21. }
    22.  
    23. //测试类
    24. public class TestClass {
    25.  
    26. /**
    27. * 区别两次new静态与非静态代码块执行情况
    28. */
    29. public static void main(String[] args) {
    30. PuTong c1 = new PuTong();
    31. c1.test();
    32.  
    33. PuTong c2 = new PuTong();
    34. c2.test();
    35. }
    36. }
    37.  
    38. /*
    39. 运行输出结果是:
    40. 静态代码块!-->非静态代码块!-->默认构造方法!-->普通方法中的代码块!
    41. 非静态代码块!-->默认构造方法!-->普通方法中的代码块!
    42. */



    有两个要点:

    1、父类、子类非静态代码块何时初始化?

    2、父类调用重写方法时,到底执行的是哪个方法?

    例子二:

    1. package tags;
    2.  
    3. public class Child extends Father{
    4.  
    5. static {
    6. System.out.println("child-->static");
    7. }
    8.  
    9. private int n = 20;
    10.  
    11. {
    12. System.out.println("Child Non-Static");
    13. n = 30;
    14. }
    15.  
    16. public int x = 200;
    17.  
    18. public Child() {
    19. this("The other constructor");
    20. System.out.println("child constructor body: " + n);
    21. }
    22.  
    23. public Child(String s) {
    24. System.out.println(s);
    25. }
    26.  
    27. public void age() {
    28. System.out.println("age=" + n);
    29. }
    30.  
    31. public void printX() {
    32. System.out.println("x=" + x);
    33. }
    34.  
    35. public static void main(String[] args) {
    36. new Child().printX();
    37. }
    38. }
    39.  
    40. class Father {
    41.  
    42. static {
    43. //System.out.println("n+"+n);
    44. //当n定义在下面时,会提示Cannot reference a field before it is defined,
    45. //所以必须把n定义移到上面才可以输出
    46. System.out.println("super-->static");
    47. }
    48.  
    49. public static int n = 10;
    50. public int x = 100;
    51.  
    52. public Father() {
    53. System.out.println("super's x=" + x);
    54. age();
    55. }
    56.  
    57. {
    58. System.out.println("Father Non-Static");
    59. }
    60.  
    61. public void age(){
    62. System.out.println("nothing");
    63. }
    64. }

     结果:

    super-->static

    child-->static

    Father Non-Static

    super's x=100

    age=0

    Child Non-Static

    The other constructor

    child constructor body: 30

    x=200

    父类静态代码块 -> 子类静态代码块

    -> 父类非静态代码块 -> 父类构造函数

    -> 子类非静态代码块 -> 子类构造函数

    java中,在使用new操作符创建一个类的实例对象的时候,开始分配空间并将成员变量初始化为默认的数值,注意这里并不是指将变量初始化为在变量定义处的初始值,而是给整形赋值0,给字符串赋值null 这一点于C++不同,(student.name = null , student.age = 0 )

    然后在进入类的构造函数。

    在构造函数里面,首先要检查是否有this或者super调用,this调用是完成本类本身的构造函数之间的调用,super调用是完成对父类的调用。二者只能出现一个,并且只能作为构造函数的第一句出现。在调用this和super的时候实现程序的跳转,转而执行被调用的this构造函数或者super构造函数。

    在this和super执行完毕,程序转而执行在类定义的时候进行的变量初始化工作。

    这个执行完毕,才是构造函数中剩下的代码的执行。

  • 相关阅读:
    Hbase教程(二) 基本操作
    Hbase教程(一) Hbase搭建
    python通过接口上传图片造测试数据
    为神马要做接口测试!
    Selenium2+python自动化25-js处理日历控件(修改readonly属性)转自-上海悠悠
    冒泡排序
    yaml入门
    Java集合--Map
    IDEA--安装
    springboot--入门(了解springboot)
  • 原文地址:https://www.cnblogs.com/zhuyeshen/p/11433566.html
Copyright © 2011-2022 走看看