详细分析java----代码块

代码块:

代码块又称初始化块,属于类中的成员(类中的一部分),类似方法,将逻辑语句封装在方法体中,通过{}包围起来,但和方法不同,没有方法名,没有返回,没有参数,只有方法体,而且不用通过方法或者类显示调用,而是加载类时,或者创建对象时隐士调用

类的加载(什么时间被加载):

我们在研究代码块,必须先知道类是什么时候被加载的,以下分为3中情况:

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

2.创建子类对象实例,父类也会被加载

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

代码块分类:

1.有static修饰的静态代码块

1.当创建对象实例时候(new)时代码块加载:

举例:

package com.test.CodeBlock;

public class Test2 {
    public static void main(String[] args) {
        SS ss = new SS();
    }
}
class SS{
   static {
        System.out.println("代码块被执行");
    }
}

运行结果:

2. 当创建子类对象实例,父类时代码块也会被加载

举例:

package com.test.CodeBlock;

public class Test2 {
    public static void main(String[] args) {
        SS ss = new SS();
    }
}
class SS extends QQ{
   static {
        System.out.println("SS代码块被执行");
    }
}
class QQ{
    static {
        System.out.println("QQ代码块被加载");
    }
}

运行结果:

 3.当使用类的静态成员时(包括静态方法和静态属性)代码块被加载:

 

package com.test.CodeBlock;

public class Test2 {
    public static void main(String[] args) {
        SS ss = new SS();
        System.out.println(ss.name);
        ss.test();
    }
}
class SS {
    public static String name="静态属性";
   static {
        System.out.println("SS代码块被执行");
    }
    public static void test(){
        System.out.println("静态成员");
    }

}

运行结果:

 

注意:
(1)作用就是对类进行初始化,随着类的加载被执行的,并且只会执行一次

举例:

package com.test.CodeBlock;

public class Test2 {
    public static void main(String[] args) {
        SS ss = new SS();
        SS ss1 = new SS();
    }
}
class SS{
    static {
        System.out.println("代码块被执行");
    }
}

运行结果:

 总结:可以从代码的运行结果上来看,当多次实例化对象时候,代码块只执行一次

(2)调用顺序

静态代码块和静态属性初始化调用的优先级是一样的,当多个静态代码块和多个静态变量初始化,则按照他们定义的顺序调用

举例:

package com.test.CodeBlock;

public class Test2 {
    public static void main(String[] args) {
        SS1 ss = new SS1();
        System.out.println("============");
        SS2 ss2 = new SS2();

    }
}
class SS1 {
    public static int age=getage();
   static {
        System.out.println("SS代码块被执行");
    }
    public static int  getage(){
        System.out.println("属性值初始化");
        return 10;
    }

}
class SS2 {
    static {
        System.out.println("SS代码块被执行");
    }
    public static int age=getage();
     public static int  getage(){
         System.out.println("属性值初始化");
         return 10;
     }
}

运行结果:

2.没有static修饰的普通代码块(非修饰代码块)

1.创建对象实例时候(new)
package com.test.CodeBlock;

public class Test3 {
    public static void main(String[] args) {
        hh hh = new hh();
    }
}
class hh{
    {
        System.out.println("代码块被调用");
    }
}

运行结果:

 

 2.创建子类对象实例,父类代码块也会被加载

举例:

package com.test.CodeBlock;

public class Test3 {
    public static void main(String[] args) {
        nn nn = new nn();
    }
}
class hh{
    {
        System.out.println("父类代码块被调用");
    }
}
class nn extends hh{
    {
        System.out.println("子类代码块被调用");
    }
}

运行结果:

 

 

注意:
(1).每创建一个对象就会执行一次

举例:

package com.test.CodeBlock;

public class Test2 {
    public static void main(String[] args) {
        SS ss = new SS();
        SS ss1 = new SS();
    }
}
class SS{
     {
        System.out.println("代码块被执行");
    }
}

运行结果:

总结:举例中创建了两个对象,可以从运行结果来看,普通代码块执行了两次,因此每创建一个对象就会执行一次

(2)调用顺序

调用普通代码块和普通属性的初始化时,调用的优先级一样的,如果多个代码块和多个普通属性初始化,则按照定义顺序调用

举例:

package com.test.CodeBlock;

public class Test3 {
    public static void main(String[] args) {
        hh hh = new hh();
        System.out.println("============");
        kk kk = new kk();
    }
}
class hh{
    {
        System.out.println("代码块被调用");
    }
    public int age= getage();
    public  int  getage(){
        System.out.println("普通属性值初始化");
        return 10;
    }
}
class kk{
    public int age= getage();
    public  int  getage(){
        System.out.println("普通属性值初始化");
        return 10;
    }
    {
        System.out.println("代码块被调用");
    }
}


运行结果:

 

构造器中隐含super()和调用普通代码块 (重点):

举例:

package com.test.CodeBlock;

public class Test4 {
    public static void main(String[] args) {
        new uu();
    }
}
class tt{
    {
        System.out.println("父类代码块被调用");
    }
    public tt() {
//     super()
//     调用本类普通代码块
        System.out.println("父类构造器被调用");
    }
}
class uu extends tt{
    {
        System.out.println("子类代码块被调用");
    }

    public uu() {
//    super()
//    调用本类普通代码块
        System.out.println("子类构造器被调用");
    }
}

运行结果:

 代码块(静态和非静态)的调用顺序:

静态代码块,静态代码块初始化,普通代码块,普通属性初始化,构造方法的调用顺序如下

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

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

4.父类的构造器

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

6.子类的构造器

 

用法1:

如果类的多个构造器中多次适用重复的语句,可以把重复的语句抽取到代码块中,提高代码的重复利用性

举例:

package com.test.CodeBlock;

public class test1 {
    public static void main(String[] args) {
        AA aa = new AA("你好");
        AA hello = new AA("hello", 1);

    }
}
class AA{
    private String name;
    private int price;
    {
        System.out.println("我喜欢吃螺蛳粉");
        System.out.println("我喜欢吃米饭");
        System.out.println("我喜欢吃面条");
    }

    public AA(String name) {
        System.out.println("AA(String name)构造器被调用");
        this.name = name;
    }

    public AA(String name, int price) {
        System.out.println("AA(String name, int price)构造器被调用");
        this.name = name;
        this.price = price;
    }
}

运行结果:

总结:当构造器被调用的时,先运行代码块中的内容,然后再运行构造器其他内容

  • 20
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值