美文网首页
java 构造函数、构造代码块与静态代码块 匿名内部类总结

java 构造函数、构造代码块与静态代码块 匿名内部类总结

作者: Auther丶 | 来源:发表于2017-09-21 10:03 被阅读82次

    转载自yeziyfx 的专栏

    构造函数、构造代码块和静态代码块容易混淆,它们的执行条件和执行顺序也常常容易犯迷。这里就针对这些问题说一下我个人的一些理解,顺便对这部分内容做个小结。

    构造函数

    格式:类名(参数1,参数2,…){构造函数执行语句};

    关于构造函数,以下几点要注意:

    1.对象一建立,就会调用与之相应的构造函数,也就是说,不建立对象,构造函数时不会运行的。

    2.构造函数的作用是用于给对象进行初始化。

    3.构造函数笼统来说也是函数,它具备函数的一些特性,也不具备一些特性,可以把它看成是特殊的函数。它可以重载(重载时参数类型与参数个数有一项不同即可,但仅仅函数返回值类型不同是不行的),可以被权限修饰符修饰,但是它没有返回值(注意:这与平常所说的函数返回值类型是void不同)。

    4.当一个类中没有定义构造函数时,那么系统会默认给该类加入一个空参数的构造方法。但是当在类中自定义构造函数后,默认的构造函数就没有了,即使是自定义的构造函数也是空参数的也是这样,因为那毕竟是你“自定义”的!

    5.构造函数和一般函数不仅在写法上有不同,在运行上也有不同。构造函数是在对象一建立就运行,给对象初始化,而一般函数是对象调用时才执行,给对象添加对象具备的功能。

    一个对象建立,构造函数只运行一次,而一般方法可以被该对象调用多次。

    6.定义构造函数的需求性:当分析事物时,该事物存在具备一些特性或者行为,那么将这些内容定义在构造函数中。

    构造代码块

    格式:{构造代码块执行语句};

    关于构造代码块,以下几点要注意:

    1.构造代码块的作用是给对象进行初始化。

    2.对象一建立就运行构造代码块了,而且优先于构造函数执行。这里要强调一下,有对象建立,才会运行构造代码块,类不能调用构造代码块的,而且构造代码块与构造函数的执行顺序是前者先于后者执行。

    3.构造代码块与构造函数的区别是:构造代码块是给所有对象进行统一初始化,而构造函数是给对应的对象初始化,因为构造函数是可以多个的,运行哪个构造函数就会建立什么样的对象,但无论建立哪个对象,都会先执行相同的构造代码块。也就是说,构造代码块中定义的是不同对象共性的初始化内容。

    静态代码块

    格式:static{静态代码块执行语句};

    关于静态代码块,要注意的是:

    1.它是随着类的加载而执行,只执行一次,并优先于主函数。具体说,静态代码块是由类调用的,当然,建立对象的时候,它也会执行,但是建立多个对象,它也是只会执行一次,并不是说每次建立对象它都要执行,因为它是由类调用的,且只执行一次!就它优先于主函数而执行这点来说,因为主函数也是由类调用的,所以类可以控制着执行的顺序,而实际上,类调用时,先执行静态代码块,然后才执行主函数的。

    2.静态代码块其实就是给类初始化的,而构造代码块是给对象初始化的。区分着理解比较容易记牢。

    下面结合一个小例子来具体分析三者的用法。

    classStaticCode{

    intnum=9;

    StaticCode(){

    System.out.println("b");

    }

    static{

    System.out.println("a");

    }

    {

    System.out.println("c");

    }

    StaticCode(intx){

    System.out.println("d");

    }

    }

    publicclassStaticCodeDemo {

    publicstaticvoidmain(String[] args){

    newStaticCode(1);

    }

    }

    运行结果是

    a

    c

    d

    这是因为,主函数中的执行语句是new StaticCode(1);因为这个语句调用了StaticCode类并调用StaticCode的一个构造函数建立对象,那么在StaticCode类中,先执行的是静态代码块

    static{

    System.out.println("a");

    }

    它是在调用类时立即执行,但此时还没有建立对象。然后执行的是构造代码块,

    {

    System.out.println("c");

    }

    这是在建立对象时执行,但它的执行是优先于构造函数的。接着执行的是对应的构造函数

    StaticCode(intx){

    System.out.println("d");

    }

    ,这个构造函数与new StaticCode(1);有着相同的参数个数和对应的参数类型,执行语句自动匹配寻找对应的构造函数。

    另外,StaticCode类中有个成员变量num,如果将静态代码块改为

    static{

    System.out.println("a"+this.num);

    }

    则编译不通过,因为静态代码块只能调用静态变量,非静态成员变量在对象没有建立前是不存在的,这也帮助理解了静态代码块是在对象建立前执行的。

    如果将构造代码块改为

    {

    System.out.println("c,num="+this.num);

    }

    那么将编译无误,运行正确,因为构造代码块是在对象建立后才运行的,是由对象调用的,对象建立后,成员变量num已经存在了,所以不会出错。

    运行结果如下

    a

    c,num=9

    d

    匿名内部类是没有构造器,那怎么来初始化匿名内部类呢?使用构造代码块!利用构造代码块能够达到为匿名内部类创建一个构造器的效果。

    new InnerClass (String arg) {

        int a;

        int b;

        {   

            a = 10;

            b = 11;

        }

    }

    1、使用匿名内部类时,我们必须是继承一个类或者实现一个接口,但是两者不可兼得,同时也只能继承一个类或者实现一个接口。

    2、匿名内部类中是不能定义构造函数的。

    3、匿名内部类中不能存在任何的静态成员变量和静态方法。

    4、匿名内部类为局部内部类,所以局部内部类的所有限制同样对匿名内部类生效。

    5、匿名内部类不能是抽象的,它必须要实现继承的类或者实现的接口的所有抽象方法

    下面是一些内部类的知识点总结博客

    内部类总结
    匿名内部类详解

    相关文章

      网友评论

          本文标题:java 构造函数、构造代码块与静态代码块 匿名内部类总结

          本文链接:https://www.haomeiwen.com/subject/wbhzsxtx.html