java基础----代码块

含义

  1. 普通代码块:常规出现在方法,循环,判断等等语句中被{}括起来的代码。
1 if(condition){
	code
}
2 for(;;){
	code
}
3 while(){
	code
}

  1. 静态代码块:在类中定义使用static修饰的代码块。
  • 它是随着类的加载而执行,只执行一次是优先于主函数的。具体来说,静态代码块是由类调用的。类调用时,先执行静态代码块,然后才执行主函数。
  • 静态代码块是给类进行初始化的
  • 静态代码块中的变量是局部变量,
  • 一个类中可以有多个静态代码块
class A{
	static {}
}
  1. 构造函数
  • 对象一旦建立就会调用与之对应的构造函数
  • 构造函数的作用是用于给对象进行初始化
  • 一个对象建立,构造函数只运行一次,而一般方法可以被对象调用多次
class A{
	A(){无参}
	A(****){有参}
}
  1. 构造代码块(非静态代码块)
  • 构造代码块的作用是给对象进行初始化
  • 对象一旦建立就运行构造代码块了,而且优于构造函数执行。注意,有对象建立的情况下才会运行构造代码块,类是不能调用构造代码块的,构造代码块的执行在构造函数之前
  • 构造函数与构造代码块的区别:构造代码块是给所有对象进行统一初始化,而构造函数是给对应的对象初始化,因为构造函数是可以有多个的,需要哪个就用哪个,而构造代码块中定义的是不同对象中相同的部分。
class A{
	{
	code
	}
}

java 各方法块的初始化顺序

对于一个类的情况

  1. 类仅仅被加载
public class codeblock {
    {
        System.out.println("这是构造代码块");
    }
    static {
        System.out.println("这是静态代码块");
    }
    codeblock(){
        System.out.println("这是构造方法");
    }

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

在这里插入图片描述
可以看出只有静态代码块运行

  1. 类被创建
public class codeblock {
    {
        System.out.println("这是构造代码块");
    }
    static {
        System.out.println("这是静态代码块");
    }
    codeblock(){
        System.out.println("这是构造方法");
    }

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

在这里插入图片描述
可以看出 先执行静态代码块,然后是构造代码块,最后是构造方法
3. 创建同一个类的两个对象

public class codeblock {
    public String name = "gg";
    {
        System.out.println("这是构造代码块"+name);
    }
    static {
        System.out.println("这是静态代码块");
    }
    codeblock(String n){
        name = n;
        System.out.println("这是构造方法"+name);
    }

    public static void main(String[] args) {
        new codeblock("A");
        new codeblock("B");
    }
}

在这里插入图片描述
同一个类中静态代码块只会被执行一次
4. 对于含有静态变量,静态初始化块,变量,初始化块,构造器的类


public class codeblock {
    public String name = "姓名";
    public static String staticname="静态name";
    {
        System.out.println(name);
        System.out.println("这是构造代码块"+name);
    }
    static {
        System.out.println(staticname);
        System.out.println("这是静态代码块");
    }
    codeblock(String n){
        name = n;
        System.out.println("这是构造方法"+name);
    }

    public static void main(String[] args) {
        new codeblock("A");
//        new codeblock("B");
    }
}

在这里插入图片描述
可以看出初始化的顺序为:静态变量、静态初始化块、变量、构造代码块、构造器

对于继承情况


class A{
    public A(){
        System.out.println("A的构造函数");
    }
    {
        System.out.println("A的构造代码块");
    }
    static{
        System.out.println("A的静态代码块");
    }
}

class B extends A{
    public B(){
        System.out.println("B的构造函数");
    }
    {
        System.out.println("B的构造代码块");
    }
    static{
        System.out.println("B的静态代码块");
    }
}

在这里插入图片描述

  1. 先执行父类的静态代码块,并初始化父类的静态成员变量
  2. 执行子类的静态代码块,并初始化子类的静态成员变量
  3. 执行父类的构造代码块,执行父类的构造函数,并初始化父类普通成员变量
  4. 执行子类的构造代码块,执行子类的构造函数,并初始化子类的普通成员变量

更进一步

class GrandParent{
    static {
        System.out.println("爷爷类的静态代码块");
    }
    {
        System.out.println("爷爷类的构造代码块");
    }
}
class Parent extends GrandParent {
    /* 静态变量 */
    public static String p_StaticStr = "父类--静态变量";
    /* 变量 */
    public String    p_Str = "父类--变量";
    protected int    i    = 9;
    protected int    j    = 0;
    /* 静态初始化块 */
    static {
        System.out.println( p_StaticStr );
        System.out.println( "父类--静态初始化块" );
    }
    /* 初始化块 */
    {
        System.out.println( p_Str );
        System.out.println( "父类--初始化块" );
    }
    /* 构造器 */
    public Parent()
    {
        System.out.println( "父类--构造器" );
        System.out.println( "i=" + i + ", j=" + j );
        j = 20;
    }
}

class SubClass extends Parent {
    /* 静态变量 */
    public static String s_StaticStr = "子类--静态变量";
    /* 变量 */
    public String s_Str = "子类--变量";
    /* 静态初始化块 */
    static {
        System.out.println( s_StaticStr );
        System.out.println( "子类--静态初始化块" );
    }
    /* 初始化块 */
    {
        System.out.println( s_Str );
        System.out.println( "子类--初始化块" );
    }
    /* 构造器 */
    public SubClass()
    {
        System.out.println( "子类--构造器" );
        System.out.println( "i=" + i + ",j=" + j );
    }

}

爷爷类的静态代码块
父类–静态变量
父类–静态初始化块
子类–静态变量
子类–静态初始化块
main
爷爷类的构造代码块
父类–变量
父类–初始化块
父类–构造器
i=9, j=0
子类–变量
子类–初始化块
子类–构造器
i=9,j=20

分析:

  1. SubClass.main()方法是一个static方法装载器寻找已经编译的SubClass类的代码。在装载的过程中发现SubClass有一个父类,于是就去装载父类,不管创不创建父类对象,都会去装载它。如果父类还有父类,那么以此类推。
  2. 执行根基类的静态代码块,之后是下一个类的静态代码块,知道这个类本身的静态代码块
  3. 所有必要的类都被装载后,开始执行main方法体,并用new SubClass() 创建对象
  4. 依次从爷爷、父亲、自己的顺序执行构造代码块以及构造方法。
  5. 对子类成员变量按照他们声明的顺序初始化,执行子类构造函数的其余部分

参考 :https://www.cnblogs.com/Qian123/p/5713440.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值