JAVA代码块

本文详细介绍了Java中的代码块,包括静态代码块和普通代码块的使用、执行顺序以及在创建对象时的调用流程。通过示例展示了类加载、对象实例化时的执行逻辑,强调了静态和非静态代码块的区别及其在构造器执行前的作用。
摘要由CSDN通过智能技术生成

基本介绍

代码块又称初始化块,属于类中的成员【即 是类的一部分】,类似与方法,将逻辑语句封装在方法体中,通过 { } 包围起来。

  但和方法不同,没有方法名、返回、参数,只有方法体,而且不用通过对象或者类显示调用,而且加载类时或创建对象时隐式调用。
 

基本语法

[ 修饰符 ] {

代码

} ;

说明注意:

1)修饰符可选,要写的话也只能写static

2)代码块分为两类,使用static 修饰符的叫静态代码块,没有static 修饰的叫普通代码块(或非静态代码块)。

3)逻辑语句可以为任意的逻辑语句(例如:输入、输出、方法调用、循环、判断等)。

4) ; 号可以写上也可以不写。

public class CodeBlock {
    public static void main(String[] args) {
        new Movie("你好!李焕英");
        System.out.println("------------------------------------------------");
        new Movie("唐人街探案3",35,"xxx");
    }

}

class Movie{
    private String name;
    private double price;
    private String director;

    {
        System.out.println("电影屏幕打开...");
        System.out.println("广告开始...");
        System.out.println("电影正式开始...");
    }

    //构造器
    //下面三个构造器都有相同的语句
    //可以把相同的语句放入到一个代码块中,不管调用哪个构造器,创建对象都会先调用代码块中的类容
    //代码块调用优先于构造器

    public Movie(String name, double price, String director) {
//        System.out.println("电影屏幕打开...");
//        System.out.println("广告开始...");
//        System.out.println("电影正式开始...");
        this.name = name;
        this.price = price;
        this.director = director;
        System.out.println("Movie(String name, double price, String director)被调用...");
    }

    public Movie(String name, double price) {
//        System.out.println("电影屏幕打开...");
//        System.out.println("广告开始...");
//        System.out.println("电影正式开始...");
        this.name = name;
        this.price = price;
        System.out.println("Movie(String name, double price)被调用...");
    }

    public Movie(String name) {
//        System.out.println("电影屏幕打开...");
//        System.out.println("广告开始...");
//        System.out.println("电影正式开始...");
        this.name = name;
        System.out.println("Movie(String name)被调用...");
    }
}

代码块使用细节

1)static 代码块也叫静态代码块,作用就是对类进行初始化,而且它随着类的加载而执行,并且只会执行一次。如果是普通代码块,每创建一个对象就执行一次

2)类在什么时候被加载(重点)

1.创建对象实例时(new)

2.创建子类对象实例,父类也会被加载(而且父类优先被加载)

3.使用类的静态成员时(静态属性、静态方法)

public class CodeBlockDetail01 {
    public static void main(String[] args) {

        //1.创建对象实例(new)
       // AA aa=new AA();

        //2.创建子类对象、实例,父类也会被加载,而且,父类先被加载,子类后被加载
        AA aa2 = new AA();
        System.out.println("---------------------------------------------");
        //3.使用类的静态成员时(静态属性、静态方法)
        System.out.println(Cat.n1);
    }
}

class AA extends BB{
    //静态代码块
    static{
        System.out.println("AA 的静态代码块被执行...");
    }
}

class BB{
    //静态代码块
    static{
        System.out.println("BB 的静态代码块被执行...");
    }
}

class Animal{
    //静态代码块
    static{
        System.out.println("Animal 的静态代码块被执行...");
    }
}

class Cat extends Animal{
    public static int n1=666;
    //静态代码块
    static{
        System.out.println("Cat 的静态代码块被执行...");
    }
}

 3)普通的代码块,在创建对象实例时,会被隐式的调用。被创建一次,就会被调用一次。如果只使用类的静态成员时,普通代码块并不会执行。

public class CodeBlockDetail02 {
    public static void main(String[] args) {

        //普通的代码块,在创建对象实例时,会被隐式的调用。
        // 被创建一次,就会被调用一次。
        DD dd1 = new DD();
        System.out.println("-------------------------");
        DD dd2 = new DD();
        
        // 如果只使用类的静态成员时,普通代码块并不会执行。
        //System.out.println(DD.n1);
    }
}

class DD{

    public static int n1=888;
    //静态代码块
    static{
        System.out.println("DD 的静态代码块被执行...");
    }

    //普通代码块,在创建对象的时候被调用,创建一次对象调用一次
    {
        System.out.println("DD 的普通代码块被执行...");
    }

}

public class CodeBlockDetail02 {
    public static void main(String[] args) {

        System.out.println(DD.n1);
    }
}

class DD{

    public static int n1=888;
    //静态代码块
    static{
        System.out.println("DD 的静态代码块被执行...");
    }

    //普通代码块,在创建对象的时候被调用,创建一次对象调用一次
    {
        System.out.println("DD 的普通代码块被执行...");
    }

}

 4)创建一个对象,在一个类调用顺序是:(重点)

1.调用静态代码块和静态属性初始化(注意:静态代码块和静态属性初始化调用的优先级别一样,如果有多个静态代码块和多个静态变量初始化,则按照他们定义的顺序调用)

2.调用普通代码块和普通属性的初始化(注意:普通代码块和普通属性初始化调用的优先级一样,如果有多个普通代码块和多个普通属性初始化,则按定义顺序调用)

3.最后调用构造器

public class CodeBlockDetail03 {
    public static void main(String[] args) {
        A a = new A();
        //运行顺序
        //(1)getN1() 被调用...  (2)A 静态代码块01
        //(3)getN2() 被调用...  (4)A 普通代码块01
        //(5)A() 构造器被调用...
    }
}

class A{
    //非静态属性初始化
    private int n2 = getN2();

    //静态属性初始化
    private static int n1 =getN1() ;

    {
        System.out.println("A 普通代码块01");
    }

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

    public static int getN1(){//静态方法
        System.out.println("getN1() 被调用...");
        return 100;
    }

    public int getN2(){//非静态方法
        System.out.println("getN2() 被调用...");
        return 200;
    }
    
    public A(){
        System.out.println("A() 构造器被调用...");
    }
}



输出结果:

getN1() 被调用...
A 静态代码块01
getN2() 被调用...
A 普通代码块01
A() 构造器被调用...

进程已结束,退出代码0

5)构造器的最前其实隐含了 super() 和调用普通代码块,静态相关的代码块,属性初始化,在类加载时就执行完毕了,因此是优先于构造器和普通代码块执行的。

 

public class CodeBlockDetail04 {
    public static void main(String[] args) {
        new BBB();
        //(1)AAA 普通代码块...
        //(2) AAA() 构造器被调用...
        //(3)BBB 普通代码块被调用...
        //(4)BBB() 构造器被调用...
    }
}

class AAA {
    {
        System.out.println("AAA 普通代码块...");
    }
    public AAA() {
        System.out.println("AAA() 构造器被调用...");
    }
}

class BBB extends AAA{
    {
        System.out.println("BBB 普通代码块被调用...");
    }
    public BBB() {
        //隐藏有super();
        System.out.println("BBB() 构造器被调用...");
    }
}


运行结果:

AAA 普通代码块...
AAA() 构造器被调用...
BBB 普通代码块被调用...
BBB() 构造器被调用...

进程已结束,退出代码0

!!!6)创建一个子类对象时(继承关系),他们的静态代码块,静态属性初始化,普通代码块,普通属性初始化,构造方法的调用顺序如下:

1.父类的静态代码块和静态属性(优先级一样,按定义顺序执行)

2.子类的静态代码块和静态属性(优先级一样,按定义顺序执行)

3.父类的普通代码块和普通属性初始化(优先级一样,按定义顺序执行)

4.父类的构造方法

5.子类的普通代码块和普通属性初始化(优先级一样,按定义顺序执行)

6.子类的构造方法

public class CodeBlockDetail05 {
    public static void main(String[] args) {

        new B02();
        //1.进行类的加载
        //1.1 先加载父类 A02,再加载B02
        //2.创建对象
    }
}

class A02 {
    private static int n1 = getVal01();//静态代码块初始化

    static {
        System.out.println("A02的一个静态代码块...//(2)输出"); //(2)输出
    }

    {
        System.out.println("A02的一个普通代码块...//(5)输出"); //(5)输出
    }

    private int n3 = getVal02();//普通代码块初始化

    public static int getVal01() {
        System.out.println("getVal01...//(1)输出");      //(1)输出
        return 10;
    }

    public int getVal02() {
        System.out.println("getVal02... //(6)输出");    //(6)输出
        return 10;
    }

    public A02() {
        //隐藏了:
        // super()
        // 普通代码块和普通属性...
        System.out.println("A02的构造器...//(7)输出"); //(7)输出
    }
}

class B02 extends A02 {
    private static int n3 = getVal03();

    static {
        System.out.println("B02的一个静态代码块...//(4)输出"); //(4)输出
    }

    public int an5 = getVal04();

    {
        System.out.println("B02的一个普通码块...//(9)输出");//(9)输出
    }

    public static int getVal03(){
        System.out.println("getVal03...//(3)输出");         //(3)输出
        return 10;
    }

    public int getVal04(){
        System.out.println("getVal04...//(8)输出");    //(8)输出
        return 10;
    }

    public B02() {
        //隐藏了
        // super()
        // 普通代码块和普通属性...
        System.out.println("B02的构造器...//(10)输出"); //(10)输出
    }
}




运行结果:

getVal01...//(1)输出
A02的一个静态代码块...//(2)输出
getVal03...//(3)输出
B02的一个静态代码块...//(4)输出
A02的一个普通代码块...//(5)输出
getVal02... //(6)输出
A02的构造器...//(7)输出
getVal04...//(8)输出
B02的一个普通码块...//(9)输出
B02的构造器...//(10)输出

进程已结束,退出代码0

7)静态代码块只能直接调用静态成员(静态属性和静态方法),普通代码块可以调用任意成员。

观看老韩视频总结

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值