普通代码块 静态代码块 构造代码块......傻傻分不清

爱写Bug的麦洛
• 阅读 1564

代码块的定义

在Java中,使用{ }括起来的代码被称为代码块。

代码块的分类

根据其位置和声明方式不同:

普通代码块 静态代码块 构造代码块......傻傻分不清

面试题: 构造块和静态块执行顺序

在上面分类描述中,我们已经给出了答案;接下来我们跑一跑测试代码,根据代码执行结果来验证这些答案

无继承关系

package com.milo.java7.codeblock;

/**
 * @author Milo Lee
 * @date 2021-04-23 15:43
 */
public class People {

    {
        System.out.println("父类构造代码块");
    }

    static {
        System.out.println("父类静态代码块");
    }

    public People() {
        System.out.println("父类构造无参构造方法");
    }
    public People(String str){
        System.out.println("父类含参构造方法");
    }

    public static void main(String[] args) {
        new People();
    }

}

执行结果:

普通代码块 静态代码块 构造代码块......傻傻分不清

现在我们改动一下代码,来看看有参情况下,执行结果会有什么变化?

 public static void main(String[] args) {
        new People("麦洛");
    }

执行结果:

普通代码块 静态代码块 构造代码块......傻傻分不清

我们发现无参构造构造方法变为含参构造方法,这个很好理解

接下来我们来看看多个对象的情况下,执行结果会有什么变化?

普通代码块 静态代码块 构造代码块......傻傻分不清

我们发现静态代码块只执行了一次,这一点要特别注意;微信搜一搜"爱写Bug的麦洛",关注我,一起努力写Bug

有继承关系

我们新建Student类来继承People类,来看看有继承关系情况下,执行结果如何

package com.milo.java7.codeblock;

/**
 * @author Milo Lee
 * @date 2021-04-23 15:44
 */
public class Student extends People {
    {
        System.out.println("子类构造代码块");
    }
    static {
        System.out.println("子类静态代码块");
    }

    public Student() {
        //super(null);
        System.out.println("子类构造代码块");
    }

    public static void main(String[] args) {
        new Student();
    }

}

执行结果:

普通代码块 静态代码块 构造代码块......傻傻分不清

如果我们换成有参的,我们来看看执行结果:

普通代码块 静态代码块 构造代码块......傻傻分不清

接下来我们来看看多个对象的情况下,执行结果会有什么变化?

普通代码块 静态代码块 构造代码块......傻傻分不清

在上面例子中,我们发现调用的都是父类无参构造方法,那么什么情况下调用父类有参构造方法呢?

首先我们改造下代码

Student

//无参构造方法
public Student() {
        super(null);
        System.out.println("子类无参构造方法");
    }

  //测试方法
  public static void main(String[] args) {
        new Student();
    }

看到了吧,就这样操作

普通代码块 静态代码块 构造代码块......傻傻分不清

代码块的作用

认识了这么多代码块,你是不是也和我一样在好奇它们的适用场景都是什么那?

普通代码块

public void show(){
    {
        System.out.println("普通代码块运行!");
    }
}

有的地方也叫局部代码块,在程序中当我们定义完成一个局部变量x之后,并且在接下来的代码中,不想再用到它时,那么就没必要让x在内存中继续占用空间。因此就有了局部代码块

构造代码块

作用在类的定义Body中,作用是给类的部分字段统一初始化:

public class Apple {
    private String size;

    //构造代码块  
    {
        System.out.println("构造代码块运行!");
        size = "E";
    }
}  

构造代码块与构造函数的区别是:构造代码块是给所有对象进行统一初始化,而构造函数是给对应的对象初始化,因为构造函数是可以多个的,运行哪个构造函数就会建立什么样的对象,但无论建立哪个对象,都会先执行相同的构造代码块。也就是说,构造代码块中定义的是不同对象共性的初始化内容。所以理所当然的,构造代码块在构造函数之前执行。

静态代码块

作用有两个: (1)给类的静态变量赋值; (2)声明静态变量;

作用在类的Body中,对类中的静态变量初始化:

public class APP {
    static int x, y; // 静态变量

    static {
        x = 5; // 给静态变量x赋值
    }

    public static void myMethod() {
        y = x++ + ++x; // x++ 先使用x的值再加1;++x先加1再使用x的值
    }

    public static void main(String[] args) {
        x--;
        myMethod();
        System.out.println(x + y + ++x);
    }
}

输出:23

注意,如果静态代码块中的代码改为:

static {
    int x = 5; // 声明一个静态变量
}

则只是在声明静态变量,而且这个静态变量的作用域只在这个代码块中,而不是进行初始化,最后的输出结果是3。

同步代码块

我们把有synchronized修饰符修饰的语句块,称为同步代码块,主要用于解决多线程下的安全问题

synchronized(Object o ){}

现在,你明白它们的作用和使用场景了吧,今天的分享就到这里,谢谢大家

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
红烧土豆泥 红烧土豆泥
3年前
简简单单复习一哈ArrayList和Arrays.asList()
1、面向对象补充(详见面试补充)基于JDK11静态代码块非静态代码块无参/有参构造在同一次编译运行时,静态代码块只会被调用一次ListArrayList(数组,初始容量为10)注:除了通过Iterator自己的remove或add方法,迭代器将抛出ConcurrentModificationException。因此,面对并
待兔 待兔
4个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Wesley13 Wesley13
3年前
java实例化
初始化块实际上,初始化块是一个假象,使用javac命令编译java类后,初始化块会消失,初始化代码被还原到每个构造器中代码的最前面在实例化的过程中:前面的初始化块先执行,后面的后执行初始化块的修饰符只能是static普通初始化块负责对对象执行初始化,静态初始化块负责对类执行初始化初始化块只在创建
Wesley13 Wesley13
3年前
Java中静态代码块、构造代码块、构造函数、普通代码块
转载来源http://www.cnblogs.com/ysocean/(https://www.oschina.net/action/GoToLink?urlhttp%3A%2F%2Fwww.cnblogs.com%2Fysocean%2F)1、静态代码块①、格式  在java类中(方法中不能存在静态代码块)使用s
Wesley13 Wesley13
3年前
Java中类的加载顺序剖析(常用于面试题)
如果类A和类B中有静态变量,静态语句块,非静态变量,非静态语句块,构造函数,静态方法,非静态方法,同时类A继承类B,请问当实例化A时,类内部的加载顺序是什么?Demo:ClassB:publicclassB{//静态变量staticinti1;//静态语句块static{
Wesley13 Wesley13
3年前
Java提高篇——静态代码块、构造代码块、构造函数以及Java类初始化顺序
静态代码块:用staitc声明,jvm加载类时执行,仅执行一次构造代码块:类中直接用{}定义,每一次创建对象时执行。执行顺序优先级:静态块,main(),构造块,构造方法。构造函数publicHelloA(){//构造函数}关于构造函数,以下几点要注意:1.对象一建立,就会调用与之相应的构造
Wesley13 Wesley13
3年前
Java类的初始化顺序 (静态变量、静态初始化块、变量、初始...
大家在去参加面试的时候,经常会遇到这样的考题:给你两个类的代码,它们之间是继承的关系,每个类里只有构造器方法和一些变量,构造器里可能还有一段代码对变量值进行了某种运算,另外还有一些将变量值输出到控制台的代码,然后让我们判断输出的结果。这实际上是在考查我们对于继承情况下类的初始化顺序的了解。我们大家都知道,对于静态变量、静态初始化块、变量、初始化块
小万哥 小万哥
10个月前
C# 循环与条件语句详解
CSwitch语句使用switch语句选择要执行的多个代码块中的一个。示例:csharpswitch(expression)casex://代码块break;casey://代码块break;default://代码块break;它的工作方式如下:1.评估