构造块、构造方法、静态代码块的执行顺序问题(阿里笔试题)

什么是代码块?

代码块既是用{ }括起来的一段代码。

代码块的分类

根据代码块的所出现的位置以及修饰它的关键字,可以将将代码块可分为以下四种:

1.局部代码块

概念:定义在方法中,用{ }括起来的一段代码。主要用来解决在方法中同名变量的定义问题。本质上是作用域和生命周期的问题。

public class  Test
{
    public static void main(String[] args)
    {
        {
            int num = 10;
            System.out.println("num="+num);
        }
        
        int num = 20;
        System.out.println("num="+num);   
    } 
 }

在这里插入图片描述
第一个num的作用域为大括号里面,程序运行时一旦出了大括号,则括号中的num出栈就不复存在了。第二个num的的作用域为定义它之后的整个主方法,在主方法中在它定以后的任何地方都能使用它(不能在它定义前使用它)。

2.构造块

概念: 定义在类中的一段代码块(不加任何修饰符)。可以用来做一些属性的初始化工作。构造块中可以调用方法。

class Student
{
    private String name;
    // 构造块
    {
        System.out.println("Studnet类的构造块");
    }
    //构造方法
    public Student()
    {
        System.out.println("Studnet类的构造方法");
    }
}
public class  Test
{
    public static void main(String[] args)
    {
        Student stu1 = new Student ();
        Student stu2 = new Student ();
    } 
 }

在这里插入图片描述
结论:可以看出构造块优先于构造方法执行,每产生一个对象则调用一次构造块和构造方法。没有对象的产生,就没有构造块和构造方法的执行,也就是说构造块和构造方法是和对象密切相关的!在构造块中也可以对属性进行初始化。

3.静态代码块

概念: 静态代码块是用static 关键字修饰,定义在类中的构造块。
分类: 1.在主类中的静态块------静态块的位置在主类中。

public class  Test
{

    public static void main(String[] args)
    {
        System.out.println("2.主方法执行");
    } 
    static
    {
        System.out.println("1.主类中的静态块");
    }
 }

在这里插入图片描述
结论:可以看出主类中的静态块优先于主方法执行。即使静态代码块的位置在主方法的后面.。
原因:JVM虚拟机运行程序时首先找主方法(主方法是程序的入口),而主方法在主类中,因此先找到主类,静态块的执行与对象无关,只要有类加载,就必然要执行静态代码块。

注:不能把静态代码块定在在主方法里面。
2.在非主类中的静态代码块。

class Student
{
    public static String name;
    static 
    {
        System.out.println("Studnet类的静态代码块");
    }
    {
        System.out.println("Studnet类的构造块块");
    }
    public Student()
    {
        System.out.println("Studnet类的构造方法");
    }
}
public class  Test
{

    public static void main(String[] args)
    {
        System.out.println("主方法执行");
        Student.name = "张三";
    }   
 }

输出结果:
在这里插入图片描述
结论:主方法优先于非主类中的静态块执行。而且静态代码块的执行与对象没有关系,没有创建任何对象,因此没有构造块和构造方法的执行。之所以静态块能执行,是因为 Student.name = “张三”;该语句访问了Student中的静态成员变量,也就是有类加载这个过程,因此静态块的执行时间由该类的加载时间而定,不论定义多少个对象,类的静态块只执行一次。静态块的作用主要是对静态属性进行初始化及对静态方法的调用。

与继承相关联的代码块的执行顺序(阿里笔试题)
class Person
{
    private String name;
    private int age;
    static
    {
        System.out.println("1.Person类的静态块");
    }

    {
        System.out.println("2.Person类的构造快");
    }

    Person()
    {
        System.out.println("3.Person类的构造方法");
    }  
}
class Worker extends Person
{
    private float salary;
    static
    {
        System.out.println("4.Worker类的静态块");
    }

    {
        System.out.println("5.Worker类的构造快");
    }

    Worker()
    {
        System.out.println("6.Worker类的构造方法");
    }  
}


public class Test
{
    public static void main(String[] args)
    {
        System.out.println("7.主方法开始执行");
        Worker work1 = new Worker();
        Worker work2 = new Worker();
        System.out.println("8.主方法执行完毕");
    }
    static 
    {
        System.out.println("9.主类的静态块");
    } 
}

输出结果:
在这里插入图片描述

分析一下:JVM虚拟机开始执行该程序,首先找主方法,因为主方法在主类中,因此必须先加载主类,主类中的静态块此时就会被执行(9),因为此时还没有用到Person,Worker类,即这两个类还没有被加载,所以它们的静态代码块不执行。然后进入主方法则显示主方法开始执行(7),在主方法中创建Worker类的对象,创建该类的对象则必然要加载该类,又因为该类继承了Person类,所以首先加载Person类,加载类的同时执行类中的静态代码块(1,4)。
因为创建了对象必然要执行构造块和调用构造方法,(在实例化子类对象前必须先实例化父类对象)因为Worker类是Person类的子类,因此首先执行Person类的构造块和调用Person类构造方法(2,3)然后再执行子类即Worker类的构造块和构造方法(5,6),因为创建了两个对象而静态块的执行仅与类加载有关,因此它只执行一次,(此时不执行1,4)接着创建第二个Worker类对象继续执行(2,3,5,6),此时两个对象已经创建完毕,执行8,所以总的执行顺序为9 7 1 4 2 3 5 6 2 3 5 6 8!

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值