• 夯实Java基础(八)——代码块


    在Java中代码块指的是使用”{}”括起来的代码称为代码块。代码块一共分为4种:局部代码块,静态代码块,同步代码块,构造代码块。

    1、局部代码块

    局部代码块就是定义在方法体内部的代码块。

    public class CodeBlockTest {
        public static void main(String[] args) {
            int i;
            {
                i=10;
                System.out.println("局部代码块"+i);
                int j=20;
                System.out.println("局部代码块"+j);
            }
            System.out.println(i);
            //Cannot resolve symbol 'j'
            //System.out.println(j);
        }
    }

    可以看到,在局部代码块中声明的变量,只能在局部代码块中进行访问。局部代码块可以操作非局部代码块的变量,但是非局部代码块不能访问局部代码块的变量。这就起到了很好的分隔,就可以用来限制局部变量的生命周期,及早释放,提高内存利用率。如果有多个局部代码块,则按照它们定义的先后顺序执行。

    2、静态代码块

    静态代码块就是在类中用static关键字修饰的代码块,它不能出现在方法体或者代码块内,我在上一篇的Static关键字中也记录了静态代码块的使用,所以就把那里的例子引用过来了。

    被static修饰的代码块也叫静态代码块,会随着JVM加载类的时候而加载这些静态代码块,并且会自动执行。它们可以有多个,可以存放在于该类的任何地方(不能放在方法内部)。JVM会按照它们的先后顺序依次执行它们,而且每个静态代码块只会被初始化一次,不会进行多次初始化。

    简单示例:

    public class Person{
    
        static {
            System.out.println("Person类静态块");
        }
    
        public Person() {
            System.out.println("Person类构造器");
        }
    
        public static void main(String[] args) {
            new Son();
            System.out.println("-------");
            new Son();
        }
    }
    
    class Son extends Person{
        static {
            System.out.println("Son类静态块");
        }
    
        public Son() {
            System.out.println("Son类构造器");
        }
    }

    运行结果:

    从运行结果分析:首先运行main()方法,然后JVM就会加载类,因为Son类继承了Person类,所以会先加载父类Person类,再去加载子类Son。由于静态代码块会随着类的加载而加载,所以先输出父类中静态代码块内容"Person类静态块",然后输出子类中静态代码块内容"Son类静态块"。加载完类之后执行main()方法内容,先new了第一个Son实例,由于子类构造器中默认调用了super(),所以先输出父类构造器的内容,再输出子类构造器的内容。之后又new了第二个Son实例,却是输出的构造器的内容,说明static静态块只加载了一次。结论:静态代码块是先加载父类的静态代码块,然后再加载子类静态代码块,是随着类的加载而加载,而且只会加载一次。

    补充:因为入口main()是个方法,也需要用类去调用,所以类的加载优先级>main()方法。

    3、同步代码块

    是使用synchronized关键字修饰的普通代码块(其只能用在方法内部)。其作用在多线程的环境下,对共享数据进行加锁, 从而实现线程同步,是一种多线程保护机制。

    public void show(){
        synchronized (obj){
            System.out.println("同步代码块");
        }
    }

    4、构造代码块

     直接在类中用"{}"定义且不加任何关键字的代码块成为构造代码块。

    public class CodeBlockTest {
    
        {
            System.out.println("构造代码块...");
        }
    
        public CodeBlockTest() {
            System.out.println("无参构造器...");
        }
    
        public static void main(String[] args) {
            new CodeBlockTest();
            new CodeBlockTest();
        }
    }

    运行结果:

    从运行结果容易看出,在创建对象时,构造代码块才会被执行,而且优先于构造方法执行(这里和构造块写前写后没关系,将构造块写在构造方法后面也是一样的结果)。而且每当有对象被创建的时,都会执行构造代码块。如果存在多个构造代码块,则执行顺序按照定义顺序依次执行。

    构造代码块的作用:可以用来初始化实例变量和实例环境(即创建对象的必要条件),这样不仅可以减少代码量,同时也可以增强程序的可读性。

    注意:构造代码块并不是真正的在构造方法之前执行的,JVM在编译的时候会把构造代码块插入到每个构造函数的最前面,构造代码块随着构造方法的执行而执行,如果某个构造方法调用了其他的构造方法,那么构造代码块不会插入到该构造方法中以免构造代码块执行多次。我们可以从编译生成的class文件可以看出来。

    5、代码块的执行顺序

    上面讲述了四种代码块的基本信息,然后我们来看一下四种代码块的执行顺序。

    public class CodeBlockTest {
    
        static {
            System.out.println("静态代码块...");
        }
    
        {
            System.out.println("构造代码块...");
        }
    
        public CodeBlockTest() {
            System.out.println("无参构造器...");
        }
    
        public void show(){
            {
                System.out.println("局部代码块...");
            }
        }
    
        public static void main(String[] args) {
            System.out.println("main()方法运行");
            new CodeBlockTest().show();
            System.out.println("----------");
            new CodeBlockTest().show();
        }
    }

    打印结果:

    执行顺序(优先级从高到低):静态代码块>mian()方法>构造代码块>构造方法>局部代码块。其中静态代码块只执行一次。构造代码块和局部代码块再每次创建对象是都会执行。

  • 相关阅读:
    Java异常的优势与缺陷,及其处理原则
    Kettle 4.2源码分析第四讲--KettleJob机制与Database插件简介(含讲解PPT)
    Kettle 4.2源码分析第三讲--Kettle 转换机制transformation介绍
    Kettle 4.2源码分析第二讲--Kettle插件结构体系简介
    Kettle 4.2源码分析第一讲--Kettle 简介
    pytorch one hot 的转换
    SQLSERVER类似于lastindexof的语句
    自定义省市选择器 微信小程序多列选择器
    王者荣耀伽罗壁纸
    微信小程序实现淡入淡出效果(页面跳转)
  • 原文地址:https://www.cnblogs.com/tanghaorong/p/11232339.html
Copyright © 2020-2023  润新知