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()
方法具有相同的参数,但是参数顺序不同,根据这个就可以区分它们。
感谢您的阅读,如果本篇文章对您有帮助,欢迎点赞,关注,您的阅读是我莫大的鼓励!