Java的初始化——详细描述Java构造器及重载过程

Java初始化和清理:

不安全的编程往往会造成代价昂贵的编程事故,其中的安全性问题有两个:初始化清理。在Java中这两个问题分别指向了构造器垃圾回收机制(Garbage Collector, GC)

构造器方法就是应用在Java中创建类对象的方法,其默认是无参构造方法,构造方法的方法名就是类名。当你创建一个对象new Rock() ,调用构造方法,创造一个新的内存空间,执行初始化操作,构造器保证对象在使用之前是被正确初始化的。

以下示例是包含了一个构造器的类:

class Rock {
    Rock() { // 这是一个构造器
        System.out.print("Rock ");
    }
}

public class SimpleConstructor {
    public static void main(String[] args) {
        for (int i = 0; i < 10; i++) {
            new Rock();
        }
    }
}

输出:

Rock Rock Rock Rock Rock Rock Rock Rock Rock Rock 

当创建的构造方法是带参数的,默认只有这一种带参构造方法,必须按照这种方法进行初始化。

this关键字

this 关键字只能在非静态方法内部使用。当你调用一个对象的方法时,this 生成了一个对象引用。你可以像对待其他引用一样对待这个引用。如果你在一个类的方法里调用其他该类中的方法,不要使用 this,直接调用即可,this 自动地应用于其他方法上了。
this关键字可调用成员变量,可调用成员方法,最重要的它可以实现在构造器中调用构造器。当你的类中重载了多个构造方法时你可以通过this关键字来调用其他构造方法完成初始化。

 Flower(int petals) {
        petalCount = petals;
    }

    Flower(String ss) {
        s = ss;
    }

    Flower(String s, int petals) {
        this(petals);
        this.s = s; 
    }

    Flower() {
        this("hi", 47);
    }
重载

任何编程语言中都具备的一项重要特性就是命名。当你创建一个对象时,就会给此对象分配的内存空间命名。方法是行为的命名。你通过名字指代所有的对象,属性和方法。良好命名的系统易于理解和修改。就好比写散文——目的是与读者沟通。

将人类语言细微的差别映射到编程语言中会产生一个问题。通常,相同的词可以表达多种不同的含义——它们被"重载"了。特别是当含义的差别很小时,这会更加有用。你会说"清洗衬衫"、“清洗车"和"清洗狗”。而如果硬要这么说就会显得很愚蠢:“以洗衬衫的方式洗衬衫”、“以洗车的方式洗车"和"以洗狗的方式洗狗”,因为听众根本不需要区分行为的动作。大多数人类语言都具有"冗余"性,所以即使漏掉几个词,你也能明白含义。你不需要对每个概念都使用不同的词汇——可以从上下文推断出含义。

大多数编程语言(尤其是 C 语言)要求为每个方法(在这些语言中经常称为函数)提供一个独一无二的标识符。所以,你不能有一个 print() 函数既能打印整型,也能打印浮点型——每个函数名都必须不同。

在 Java (C++) 中,还有一个因素也促使了必须使用方法重载:构造器。因为构造器方法名肯定是与类名相同,所以一个类中只会有一个构造器名。那么你怎么通过不同的方式创建一个对象呢?例如,你想创建一个类,这个类的初始化方式有两种:一种是标准化方式,另一种是从文件中读取信息的方式。你需要两个构造器:无参构造器和有一个 String 类型参数的构造器,该参数传入文件名。两个构造器具有相同的名字——与类名相同。因此,方法重载是必要的,它允许方法具有相同的方法名但接收的参数不同。尽管方法重载对于构造器是重要的,但是也可以对任何方法很方便地进行重载。

如果两个方法命名相同,Java是怎么知道你调用的是哪个呢?有一条简单的规则:每个被重载的方法必须有独一无二的参数列表。你稍微思考下,就会很明了了,除了通过参数列表的不同来区分两个相同命名的方法,其他也没什么方式了。你甚至可以根据参数列表中的参数顺序来区分不同的方法,尽管这会造成代码难以维护。例如:

// housekeeping/OverloadingOrder.java
// Overloading based on the order of the arguments

public class OverloadingOrder {
    static void f(String s, int i) {
        System.out.println("String: " + s + ", int: " + i);
    }

    static void f(int i, String s) {
        System.out.println("int: " + i + ", String: " + s);
    }

    public static void main(String[] args) {
        f("String first", 1);
        f(99, "Int first");
    }
}

输出:

String: String first, int: 1
int: 99, String: Int first

两个 f() 方法具有相同的参数,但是参数顺序不同,根据这个就可以区分它们。

感谢您的阅读,如果本篇文章对您有帮助,欢迎点赞,关注,您的阅读是我莫大的鼓励!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值