• 图解 & 深入浅出Java初始化与清理:构造器必知必会


    Writer      :BYSocket(泥沙砖瓦浆木匠)

    微         博:BYSocket

    豆         瓣:BYSocket

    FaceBook:BYSocket

    Twitter    :BYSocket

    面向对象编程中,编程人员应该在意“资源”。比如

    1
    <font color="#000000">String hello = "hello"; </font>

    在代码中,我们很在意在内存String类型hello,它是有一个生命周期的。在它生命周期中,初始化(initialization)清理(cleanup)是两个重要的环节。尤其是C程序中,很多bug会出现在对象初始化清理的环节。这样会造成一些程序安全问题。

    《Think in Java》中说道:

    随着计算机革命的发展,”不安全“的编程方式已逐渐成为编程代价高昂的主因之一。

    一、栈与堆

    在Java开发中,针对对象会在乎内存的两个区域:对象的生存空间是堆(heap) — 方法调用及局部变量(也称变量)的生存空间栈(stack)。如图:

    绘图1

    二、什么是构造器,默认(无参)构造器

    为了保证对象成功初始化,Java像C++一样引入了构造器(Constructor),即在创建对象的时候被自动调用的特殊方法。自然,Java额外提供了GC(垃圾回收器),对于不再使用的资源,垃圾回收机制会自动释放资源。Java通过类构造器创建新对象的时候,在使用此对象前,会调用其构造器进行初始化。如:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    <font color="#000000">public class VoidConstructor {
         
        VoidConstructor(){
            // 构造器
        }
         
        void VoidConstructor() {
            // void 方法,不是构造器
        }
    }</font>

    1、默认构造器

    这里,VoidConstructor是一个类,如果需要创建一个VoidConstructor对象只要

    1
    <font color="#000000">VoidConstructor constr = new VoidConstructor();</font>

    调用上面的代码就可以通过这个默认构造器(即无参构造器),就生成一个VoidConstuctor对象。代码图解如下

    绘图2

    2、注意,构造器特殊方法,采取与类名同名。它没有返回值,这与返回值void方法不同。这里,void方法名命名也是不规范,应该是“每个方法首字母小写”,也一般不与类名相同。 

    另外,就算你类没有写构造器的话,编译器会生成一个默认构造器。

    三、带参构造器

    下面跑个带参构造器的例子:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    /**
     * @author Jeff Lee
     * @since 2015-9-7 16:54:19
     * 带参数简单构造器的展示
     */
    public class SimpleConstructor2 {
        public static void main(String[] args) {
            for (int i = 0; i < 10; i++) {
                new Child2(i);
            }
        }
    }
     
    // Child类
    class Child2 {
        Child2(int i) {// 带参数的Child类构造器
            System.out.print("Child init " + i + " ");
        }
    }

    Eclipse中,右键Run as — java application

    image

    上面Child2(int)是Child类的唯一构造器,此时你先在编译器中通过 new Child2()来创建对象是不行的。

    所以,构造器有助于避免开发中出现代码错误

    二者,构造器可以用来初始化资源。其中,对象的创建与资源的初始化是捆绑在一起的。

    休息一下吧~ 看看小广告:

    开源代码都在我的gitHub上哦 — https://github.com/JeffLi1993 作者留言“请手贱,点项目star,支持支持拜托拜托

    四、继承中的构造器

    在创建一个对象时,所以继承下来的对象都会被调用各构造器。比如说下面这个例子:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    /**
     * @author Jeff Lee
     * @since 2015-9-10 08:56:18
     * 继承中的构造器的案例
     */
    public class ChildConstructor extends PersonConstructor{
        ChildConstructor() {<br>                  //super();
    <br>        System.out.println("Making a Child Modle...");
        }
         
        @SuppressWarnings("unused")
        public static void main(String[] args) {
            ChildConstructor childConstructor = new ChildConstructor();
        }
    }
     
    class PersonConstructor {
        PersonConstructor() {
            System.out.println("Making a Person Modle...");
        }
    }

    main函数运行结果如下:

    image

    1. 先分析下类UML,ChildConstructor 继承 PersonConstructor,PersonConstructor 继承 Object:

    绘图3

    2. super关键字,super用来调用父类的构造器。如果子类中没有super关键字,编译器会自动添加默认super()方法。因此,子类通过super()方法调用父类构造器。

    3. 然后main函数中,通过new指令,启动了ChildConstructor对象的创建。子类 ChildConstructor 构造器在执行时,第一件事通过super()调用父类,这又会连锁反应到Objerct类。所以,打印控制台先输出 “父类先初始化”。

    这过程就是构造器链Constructor Chaining),即Child对象  is-a Person对象同时也 is-a Object对象。如果创建Child对象,也同时创建了Person对象和Object对象的部分。

    4. 过程流程图详解(图中是各对象引用在堆栈块):

    绘图4

    五、总结

    构造器虽小,关键还是非常关键的。

    本文小结:

    1、默认构造器

    2、有参构造器

    3、继承中的构造器

    还有第一点的知识基础补充

    欢迎点击我的博客及GitHub — 博客提供RSS订阅哦!

    ———- http://www.bysocket.com/ ————- https://github.com/JeffLi1993 ———-

  • 相关阅读:
    [51nod 1129] 字符串最大值(kmp)
    P3391 【模板】文艺平衡树(Splay)
    次大公约数
    青蛙的约会
    [HNOI2002]营业额统计
    GYM 100741A Queries
    P3370 【模板】字符串哈希
    P3369 【模板】普通平衡树(Treap/SBT)
    05:LGTB 与偶数
    简单计算器
  • 原文地址:https://www.cnblogs.com/Alandre/p/4798780.html
Copyright © 2020-2023  润新知