Java中的静态代码块与非静态代码块

柔光的暖阳◎ 2023-05-30 10:56 218阅读 0赞

时间:2019/11/10

一.静态代码块

1.问题

(1)静态代码块随着类的加载类的加载而执行,而且只执行一次

(2)在同一个类中,静态代码块的执行顺序优先于main函数

(3)继承中静态代码块的执行顺序

2.问题一

针对问题一,我们先看下面这段代码:

  1. public class Main_Test{
  2. public static void main(String[]args){
  3. new One().lianxi();
  4. new One().lianxi();
  5. }
  6. }
  7. class One{
  8. public void lianxi(){
  9. System.out.println("函数被执行");
  10. }
  11. static{
  12. System.out.println("静态代码块被执行);
  13. }
  14. }

结果为:

20191110123020309.png

在上述代码中,我们创建了两个匿名的One对象,但是静态代码块只被执行了一次,而且在代码中,静态代码块写在lianxi函数的后面,但是执行的时候先执行的是静态代码块.

问题二

针对问题二,我们看下面这段代码:

  1. public class Test_One{
  2. static{
  3. System.out.println("静态代码块被执行");
  4. }
  5. public static void main(String[] args){
  6. System.out.println("main函数被执行");
  7. }
  8. }

运行结果为:

20191110123825465.png

在上述代码中,main方法所在主类首先被加载,根据问题一中结论,主类被加载时会运行静态代码块,而且从运行结果中我们可以看出,静态代码块在执行时先于main方法执行.

问题三

针对问题三,我们来看一下下面这段代码:

  1. public class Test_Three{
  2. public static void main(String[] args){
  3. new Two();
  4. }
  5. }
  6. class One{
  7. static{
  8. System.out.println("父类中的静态代码块被执行");
  9. }
  10. public One(){
  11. System.out.println("父类的构造方法被执行");
  12. }
  13. }
  14. class Two extends One{
  15. static{
  16. System.out.println("子类中的静态代码块被执行");
  17. }
  18. public Two(){
  19. //子类构造方法的第一行必须调用父类的构造方法,这里默认调用父类无参的构造方法
  20. System.out.println("子类的构造方法被执行");
  21. }
  22. }

结果为

20191110125537110.png

通过上述结果我们可以看出,当存在继承关系时,会先调用父类的静态代码块,然后调用子类的静态代码块,然后调用父类的构造方法,最后调用子类的构造方法.

二.非静态代码块

1.问题

(1)非静态代码块每创建一次对象就执行一次.

2.问题一

先看一下下面这段代码:

  1. public class Test_Four{
  2. {
  3. System.out.println("非静态代码块被执行");
  4. }
  5. public static void main(String[] args){
  6. System.out.prinltn("main函数被执行");
  7. }
  8. }

结果为:

20191110130556276.png

再看一段代码:

  1. public class Test_Four{
  2. public static void main(String[] args){
  3. System.out.println("main方法被调用");
  4. new Five();
  5. System.out.println("main方法被调用");
  6. }
  7. }
  8. class Five{
  9. {
  10. System.out.println("静态代码块被执行");
  11. }
  12. public Five(){
  13. System.out.println("构造方法被调用");
  14. }
  15. }

结果为:

20191110131154659.png

对比两段代码的结果我们发现,非静态代码块不是在类加载时被调用的,而是在对象创建时被调用的,并且每创建一个对象就会被调用一次,即可以执行多次,而且执行的优先级要比静态代码块低很多,这从main方法的打印语句可以在非静态代码块之前被执行就可以看出来.

三.总结

通过下面这段代码汇总一下静态代码块和非静态代码块的执行顺序:

  1. package cn.machi12;
  2. public class Test_Five extends Six{
  3. static{
  4. System.out.println("子类的静态代码块被调用");
  5. }
  6. {
  7. System.out.println("子类的非静态代码块被调用");
  8. }
  9. public Test_Five(){
  10. System.out.println("子类的构造方法被调用");
  11. }
  12. public static void main(String[] args){
  13. System.out.println("main函数被调用");
  14. new Test_Five();
  15. }
  16. }
  17. class Six{
  18. static{
  19. System.out.println("父类的静态代码块被调用");
  20. }
  21. {
  22. System.out.println("父类的非静态代码块被调用");
  23. }
  24. public Six(){
  25. System.out.println("父类的构造方法被调用");
  26. }
  27. }

结果为:

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L21hY2hpMQ_size_16_color_FFFFFF_t_70

我们对上述结果进行分析:
首先被调用的父类中的静态代码块,其后的是子类中的静态代码块,然后是main函数中的语句(如果main函数的语句在创建对象语句之前),再之后是父类的非静态代码块和父类的构造方法,最后是子类的非静态代码块和子类的构造方法.

参考博文:

1.https://blog.csdn.net/sinat_33921105/article/details/79509638

2.https://blog.csdn.net/weixin_36910300/article/details/78643455

发表评论

表情:
评论列表 (有 0 条评论,218人围观)

还没有评论,来说两句吧...

相关阅读