zoukankan      html  css  js  c++  java
  • java中static 静态变量、静态常量和静态代码块的执行顺序与区别

    众所周知 在android中static 修饰的会被称之为 静态常量,静态变量, 静态方法 ,还有就是静态代码块,用static{ // 代码块 非static修饰的方法,变量,常量, 是不能再静态代码块中使用的 } 表示。

           static修饰的 是跟着类走的, 而不是跟随对象,这个大家都是知道的。 那么大家是否知道它们之间的运行顺序的关系呢? 今天, 我就给大家简单讲解一下吧。

           静态常量,静态变量,静态方法, 大家都知道是通过类名直接调用的(例如:Demo.getStatic() )。但是静态代码块 大家都没有主动调用过 对吧。 那它 到底什么时候被执行呢? 让我来揭晓吧, 其实只要你的代码在任意地方,动用了静态代码块所属的类中的 任意东西, 那么该静态代码块 就会马上执行(说白了就是  静态代码块是这个类最先执行的代码, 但前提是你要使用这个类, 不使用的话, 这个类中的静态代码块是不会执行的 与静态变量相比就是看代码编写的前后顺序,和静态方法有很大的区别)。 当一个类中 有多个静态代码块的时候,是按照代码编写的上下顺序先后执行的。

          静态代码块 与 静态变量之间的关系:

    如果你想正确使用两者的话, 个人建议  你必须把静态变量定义在静态代码块的前面, 因为两个的执行是会根据代码编写的顺序来决定的。这个比较难理解, 我来举个例子吧, 情况下面代码:

    public class Demo{

              public static int i;

              static{

                    i = 20;

                    //这里的i, 是可以被用作运算的。

               }

    }

    这时候如果你在main函数输出i, 那么i=20;

    public class Demo{  

              static{

                    i = 20;

                 //这里的i, 是不能被用作运算的, 因为本质上 i 还未被定义

               }

              public static int i;

    }

    这时候如果你在main函数输出i, 那么i=20;

     public class Demo{  

              static{

                    i = 20;

                 //这里的i, 是不能被用作运算的, 因为本质上 i 还未被定义

               }

              public static int i = 1;

    }

    //但是如果我们给静态的i附上一个初始值后,那么结果就变了。

    这时候如果你在main函数输出i, 那么i=1;

    上述的代码 就其实就是进一步说明 静态变量 和static修改的静态代码块 运行的顺序是根据代码编写的先后, 而且第二种写法毫无意义。 未了避免出现不必要的麻烦, 本人强制建议, 不管是否有在静态代码块中使用 静态变量, 都应当把静态变量写在 静态代码块的上方。 静态常量的情况 和静态变量是一样, 这里就不在做说明了。

    1、执行顺序

    1.1、一个类中的初始化顺序

    类内容(静态变量、静态初始化块) => 实例内容(变量、初始化块、构造器)

    1.2、两个具有继承关系类的初始化顺序

    父类的(静态变量、静态初始化块)=> 子类的(静态变量、静态初始化块)=> 父类的(变量、初始化块、构造器)=> 子类的(变量、初始化块、构造器)

    示例如下:(结果见注释)

    复制代码
    复制代码
     1 class A {
     2     public A() {
     3         System.out.println("Constructor A.");
     4     }
     5 
     6     {
     7         System.out.println("Instance Block A.");
     8     }
     9     static {
    10         System.out.println("Static Block A.");
    11     }
    12 
    13     public static void main(String[] args) {
    14         new A();/*
    15                  * Static Block A. Instance Block A. Constructor A.
    16                  */
    17     }
    18 }
    19 
    20 class B extends A {
    21     public B() {
    22         System.out.println("Constructor B.");
    23     }
    24 
    25     {
    26         System.out.println("Instance Block B.");
    27     }
    28     static {
    29         System.out.println("Static Block B.");
    30     }
    31 
    32     public static void main(String[] args) {
    33         new A();/*
    34                  * Static Block A. Static Block B. Instance Block A. Constructor A.
    35                  */
    36         System.out.println();
    37         new B();/*
    38                  * Instance Block A. Constructor A. Instance Block B. Constructor B.
    39                  */// 静态成员和静态初始化块只会执行一次。
    40     }
    41 }
    复制代码
    复制代码

    2、对变量值的影响

    一个变量,若显示初始化、初始化块对该变量赋值、构造方法对该变量赋值同时存在,则变量最终值如何确定?按1节中所述的执行顺序确定。

    这里考虑初始化块在变量定义之前的情形,此时会造成迷惑。

    初始化块可以对在它之后定义的变量赋值,但不能访问(如打印)。如:

    1     static {
    2         a = 3;
    3         // int b=a;//Cannot reference a field before it is defined
    4         // System.out.println(a);//Cannot reference a field before it is defined
    5     }
    6     static int a = 1;

    “对变量值的影响”是指 对变量赋值的初始化块位于变量定义之前 时,变量的最终值根据变量定义时是否显示初始化而会有不同结果(若初始化块位于变量定义之后,那么变量的值显然很容易就确定了,不会造成迷惑)。如:

     
     
     

     3、总结

    执行顺序:

    1、类内容(静态变量、静态初始化块) => 实例内容(变量、初始化块、构造器)

    2、父类的(静态变量、静态初始化块)=> 子类的(静态变量、静态初始化块)=> 父类的(变量、初始化块、构造器)=> 子类的(变量、初始化块、构造器)

    初始化块可以对在它之后定义的变量赋值,但不能访问(如打印)。

    变量最终值:一个变量,若显示初始化、初始化块对该变量赋值、构造方法对该变量赋值同时存在,则变量最终值如何确定:

    1、按执行顺序

    2、若对变量赋值的初始化块在变量定义前时:若变量显示初始化了则最终为显示初始化值,否则为初始化块的赋值。

    原文链接:https://www.cnblogs.com/zhuyeshen/p/12684038.html

    linux下的docker操作命令及异常
  • 相关阅读:
    作业插入一个数值,按顺序排列
    元旦作业输入一批数字求最大最小值,用户输入一位整数,显示对应英文星期缩写,筛子游戏完善
    2018/12/29测试题
    JAVA循环的语法
    课后作业机票,赌骰子游戏,switch的使用实例
    Cadence之双击(DSN/brd)文件打开变新建文件的解决方法
    STemwin替换为MDK下的emwin
    Orcad原理图封装库批量编辑引脚时需要配合Excel进行制作时候需要操作(遇到无法复制粘贴操作)
    偶遇STM32 JTAG和SWD口(调试)被禁用无法下载,已经粗暴解决!
    Altium Designer之AD16在Win10系统下无法切换走线/布线模式的解决办法
  • 原文地址:https://www.cnblogs.com/ketoli/p/14539646.html
Copyright © 2011-2022 走看看