JAVA中代码块的理解

1. 代码块

语法:{/代码内容},

{
    System.out.println("这是一个代码块");
}
  1. 不需要方法体的名称,那么这个在程序中的作用是什么呢,如我们java代码中的构造器,我们java在创建实例的时候 new的是一个无参构造器,而这个构造器做了对类与对象的初始化,例如给对象开辟空间,如果是有参构造还会初始化给属性赋值等等,那么代码块的作用也是在加载类的时候做一个初始化的动作
    类在什么时候会被加载:1,创建对象实例时。2,创建子类对象实例,父类也会被加载。3,使用类的静态成员时(1,加载静态属性、2,加载静态方法)

  2. 代码块分为普通代码块和静态代码块,普通代码块依附对象存在,在这个类被创建对象的时候才会被加载,而静态代码块无论创建多少次实例,直到生命周期的截止,这个静态代码块只会执行一次

  3. 代码块的执行顺序,静态代码块大于>普通代码块>构造器,当一个子类继承父类后,执行顺序是
    (1)子类的父类的静态属性和代码块优先加载。(2)加载子类的静态属性与静态代码块 (3)加载父类的普通代码块和构造器 (4)加载子类的普通代码块和构造器

  4. 下面我们首先来看不是继承的代码输出顺序

class A {
    static  int  s=aaa();
    static{
        System.out.println("A类的静态代码块被访问");
    }
    {
        System.out.println("普通代码块:A类的");
    }
    public  static int   aaa(){
        System.out.println("给A类的属性s赋值成功");
        return 8;
    }
    public A(){
        System.out.println("A类的构造方法被访问");
    }

}
public static void main(String[] args) {
 A A=new A();
    A A1=new A();

}

(1) A A=new A(); 输出的结果是

  1. 给A类的属性s赋值成功

  2. A类的静态代码块被访问

  3. 普通代码块:A类的

  4. A类的构造方法被访问
    (2) A A1=new A(); 输出的结果是

  5. 普通代码块:A类的

  6. A类的构造方法被访问
    因此静态属性和今天代码块和前面文章中说过的静态关键字static 是一样的,随着类的加载而加载的,那么直接使用A访问静态属性会输出普通代码块吗? 答案是不会的,因为普通代码块是依附对象存在的,对象在创建实例的时候才会初始化,但初始化的过程中也将静态的相关信息加载进去了,属于全局加载,而直接用A访问静态属性那么只会加载今天相关的代码比如将上面的main方法的代码修改为

public static void main(String[] args) {
System.out.println(A.s);

}

那么输出信息如下

  1. 给A类的属性s赋值成功
  2. A类的静态代码块被访问
  3. 8
    那么当这个A类被继承后 ,执行顺序是什么呢,答案:A与继承类的静态属性与代码块优先程序,如果多个静态代码块则按照从上到下的顺序依次执行,当继承类与A类的静态属性与静态代码块加载完毕后,加载父类的普通代码块和构造器,之后加载子类的普通代码块和构造器,前面已经说了这个顺序了,如下是代码测试
class A {
    static  int  s=aaa();
    static{
        System.out.println("A类的静态代码块被访问");
    }
    {
        System.out.println("普通代码块:A类的");
    }
    public  static int   aaa(){
        System.out.println("给A类的属性s赋值成功");
        return 8;
    }
    public A(){
        System.out.println("A类的构造方法被访问");
    }

}
class B extends A{
    {
        System.out.println("普通B类代码块:");
    }
    static{
        System.out.println("B类的静态块被访问");
    }
    public B(){
        System.out.println("B类的构造方法被访问");
    }
}
public static void main(String[] args) {
B B=new B();

}

输出结果是

  1. 给A类的属性s赋值成功
  2. A类的静态代码块被访问
  3. B类的静态块被访问
  4. 普通代码块:A类的
  5. A类的构造方法被访问
  6. 普通B类代码块:
  7. B类的构造方法被访问
    因为构造器中其实隐含了super()和调用普通代码块的代码,super指向的就是父类的构造器,而静态属性与静态代码块在创建实例时优先于其他代码,因此父类的静态代码优先加载子类的静态后加载,之后再去加载父类的普通代码块与构造器,在加载子类的普通代码块与构造器,如果上面的代码例子中,B创建了2次实例那么 给A类的属性s赋值成功、A类的静态代码块被访问、B类的静态块被访问 也只是输出一次。但普通的代码块和构造器则是创建一次实例便出现一次。

并且A类在加载了静态属性S后,B类是可以直接访问的,这个在堆栈方法区有一个区域,是专门放置了静态属性的空间的,一次加载,一直都在,只是看使用的这个类什么时候结束运行,生命周期是随着使用类的加载开始,随着使用类的消亡而消亡

public static void main(String[] args) {
System.out.println(B.s);
}

输出结果是

  1. 给A类的属性s赋值成功
  2. A类的静态代码块被访问
  3. 8
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值