前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Java中静态代码块、构造代码块、构造函数、普通代码块

Java中静态代码块、构造代码块、构造函数、普通代码块

作者头像
Fisherman渔夫
发布2019-07-31 15:50:07
1.5K0
发布2019-07-31 15:50:07
举报
文章被收录于专栏:渔夫渔夫
知识共享许可协议
知识共享许可协议

版权声明:署名,允许他人基于本文进行创作,且必须基于与原先许可协议相同的许可协议分发本文 (Creative Commons

一、格式区分及其性质

1.静态代码块

 Java使用static{//Code...}的格式代表静态代码块。位置:位于类内,与方法同层次

代码语言:javascript
复制
public class Test{
    static{
	//Code...
    }
}

 静态代码块会随着类的加载而执行,而且只执行一次,并且优先于各种代码块以及构造函数。一个类中若有多个静态代码块,则顺序执行它们。另一方面,静态的代码块也不能访问非静态域。  静态代码块的作用:一般情况下,如果有些代码需要在项目启动的时候就执行,这时候就需要静态代码块。比如一个项目启动需要加载的很多配置文件等资源,我们就可以都放入静态代码块中。

2.构造代码块

 Java使用{//Code...}的格式代表构造代码块,对比于静态代码块,其只少了static关键字的修饰。位置:位于类内,与方法同层次

代码语言:javascript
复制
public class Test {
    {
	//Code...
    }
}

 构造代码块在对象每次创建类的对象的时候都会被调用,显然可以用于对每个对象的独立初始化工作,比如对每个对象进行增序的编号。

3.构造函数

 Java使用与类同名的方法(有参或无参){//Code...}的格式代表构造函数。位置:位于类内,是一个作用特殊的方法

代码语言:javascript
复制
public class Test {
	public Test(){
	//Code...
    }
}

 构造函数和构造代码块的区别是,所有构造代码块在每个对象创建的时候都会执行,但是构造函数因为Java中的多态语法只会执行一个,并非是所有都进行执行。

4.普通代码块

 Java使用{//Code...}的格式代表构造代码块,对比于构造代码块,其区别是普通代码块跑到方法内部了。位置:位于方法内部。

代码语言:javascript
复制
public class Test {
	public void method(){
	//Code1...
	{
	//Code2...
	}
    }
}

 普通代码块的执行顺序和书写顺序一致(与方法体内部的代码比较执行顺序)。比如上述Code1先于Code2执行。


二、代码块的执行顺序

 为了说明四个代码块的执行顺序,我特意将其执行的顺序的逆序来编写代码(顺便将main方法纳入顺序比较):

Demo-1:

代码语言:javascript
复制
public class CodeBlock {
    static int i = 0;


    public CodeBlock() {
        System.out.printf("构造函数第%d个执行\n", ++i);
        {
            System.out.printf("普通代码块第%d个执行\n", ++i);
        }
    }

    {
        System.out.printf("构造代码块第%d个执行\n", ++i);
    }

    public static void main(String[] args) {
        System.out.println("执行main方法");
        CodeBlock codeBlock = new CodeBlock();

    }

    static {
        System.out.printf("静态代码块代码块第%d个执行\n", ++i);
    }

}

控制输出:

代码语言:javascript
复制
静态代码块代码块第1个执行
执行main方法
构造代码块第2个执行
构造函数第3个执行
普通代码块第4个执行

执行顺序:  静态代码块->构造代码块->构造函数->普通代码块 注意事项

  1. 普通代码块可以嵌入其余任何一个代码块中,且前三代码块内部代码都是顺序执行的;
  2. main方法晚于静态代码块执行,但是main内部的方法和其余三个代码块是顺序执行的;

三、涉及继承的代码块执行顺序

Demo-2:

代码语言:javascript
复制
public class CodeBolckExtends {
    public static void main(String[] args) {
        Son son = new Son();
    }
}


class  GrandPa{
    static int i =0;
    static {
        System.out.printf("父类的父类的静态代码块第%d个执行\n",++i);
        }

    public GrandPa() {
        System.out.printf("父类的父类的构造函数第%d个执行\n",++i);
    }
}

class Father extends GrandPa{
    static {
        System.out.printf("父类的静态代码块第%d个执行\n",++i);
    }
    public Father() {
        System.out.printf("父类的构造函数第%d个执行\n",++i);
    }
}



class Son extends Father{
    static {
        System.out.printf("子类的静态代码块第%d个执行\n",++i);
    }
    public Son() {
        System.out.printf("子类的构造函数第%d个执行\n",++i);
    }
}

控制台输出:

代码语言:javascript
复制
父类的父类的静态代码块第1个执行
父类的静态代码块第2个执行
子类的静态代码块第3个执行
父类的父类的构造函数第4个执行
父类的构造函数第5个执行
子类的构造函数第6个执行

 根据Demo-2代码实验可知,涉及继承的代码块执行顺序是这样的:  父类的静态方法->子类的静态方法->父类的构造代码块->父类的构造函数->子类的构造代码块->子类的构造函数 相关原理以及解释:

  1. 因为static修饰的代码在类加载的时候就进行执行,而类加载是先于对象创建的,所以子类和父类的静态方法要首先执行。又因为保护继承成立,我们无论是类加载,还是对象的创建,都是父类先行的,所以静态方法内部执行顺序是父类先于子类的。即:父类的静态方法->子类的静态方法。
  2. 对象的创建也因为如上继承的原因,父类对象先应当构造。注意:虽然有构造代码块先于构造函数执行的顺序这个原则,但是要保证父类对象成功安全地构造之后才应该构造子类对象,否则继承被破坏。所以有“父类的构造代码块->父类的构造函数->子类的构造代码块->子类的构造函数”如此的执行顺序。
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019年07月28日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、格式区分及其性质
    • 1.静态代码块
      • 2.构造代码块
        • 3.构造函数
          • 4.普通代码块
          • 二、代码块的执行顺序
          • 三、涉及继承的代码块执行顺序
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档