随着计算机革命的发展,“不安全”的编程方式已逐渐成为编程代价高昂的原因之一。
初始化和清理(cleanup)正是涉及安全的两个问题。以C语言来说,很多的C程序错误都来源于程序员忘记初始化变量。特别是在使用程序库时,如果用户不知道如何初始化库的构件(或者是用户必须进行初始化的其他东西),更是如此。清理也是一个特殊问题,当使用完一个元素时,它对你也就不会有什么影响了,所以很容易就把它忘记。这样一来,这个元素占用的资源就会一直得不到释放,结果导致资源(尤其是内存)耗尽。
C++引入了构造器(constructor)的概念,这是一个在创建对象时就会自动调用的特殊方法。Java中也采用了构造器,并额外提供了“垃圾回收器”。对于不在使用的内存资源,垃圾回收期能自动将其释放。
接下来我们就说说初始化和清理的相关问题,以及Java对他们提供的支持。
构造器确保初始化
可以假想为编写的每个类都定义一个initialize()方法。该方法的名称提醒你在使用其对象之前,应首先调用initialize()。然而,这同时意味着用户必须记得自己起调用这个方法。在Java中,通过提供构造器,类的设计者可确保每个对象都会得到初始化。创建对象时,如果其类具有构造器,Java就会在用户有能力操作对象之前自动刚调用相应的构造器,从而保证了对象初始化的进行。
接下来的问题就是如何命名这个方法了。有两个问题:第一,所取的任何名字都有可能与类的某个成员名称相冲突;第二,调用构造器是编译器的责任,所以必须让编译器知道应该调用哪个方法。C++语言中采用解决方案看起来简单且更符合逻辑,所以在Java中也才用了这种方案:即构造器采用与类相同的名称。考虑到初始化期间要自动调用构造器,这种做法就顺理成章了。
下面就是一个带有构造器的简单类:
// initialzation // 演示一个简单的构造器示例 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 */
现在,在创建对象的时候:
new Rock();
将会为对象分配存储空间,并调用相应的构造器。这就确保了在你能操作对象之前,它已经被恰当的初始化了。
请注意,由于构造器的名称必须与类名完全相同,所以“每个方法首字母小写”的编码风格并不适用于构造器。
不接受任何参数的构造器叫做默认构造器,Java文档中通常使用术语无参构造器,但是默认构造器在Java出现前就已经使用多年了,所以我人就倾向于使用它。但是和其他方法一样,构造器也能带有形式参数,以便制定如何创建对象。对上述例子稍加修改,即可使构造器接受一个参数:
// initialzation // 演示一个简单的构造器示例 class Rock{ Rock() { // System.out.print("Rock "); } Rock(int i) { System.out.print("Rock " + i + " "); } } public class SimpleConstructor { public static void main(String[] args) { for (int i = 0; i < 10; i++) { new Rock(); } System.out.println(""); for (int i = 0; i < 10; i++) { new Rock(1); } } }
/* Output:
Rock 1 Rock 1 Rock 1 Rock 1 Rock 1 Rock 1 Rock 1 Rock 1 Rock 1 Rock 1 * /
有了构造器形式参数,就可以在初始化对象时提供实际参数。例如,假设类Tree有一个构造器,它接受一个整型变量来表示数的高度,就可以这样创建一个Tree对象:
Tree t = new Tree(21); // 21-foot tree
如果Tree(int)是Tree类中唯一的构造器,那么编译器将不会允许你以其它任何方式创建Tree对象。
构造器有助于减少错误,病史代码更易于阅读。从概念上讲,初始化和创建是彼此独立的,然而在上面的代码中,你却找不到initialize()方法的明确调用。在Java中,“初始化”和“创建”捆绑在了一起,两者不能分离。
构造器是一种特殊类型的方法,因为他没有返回值。这与返回值为空(void)明显不同。对于空返回值,尽管方法本身不会自动返回什么,但仍可选择让他返回别的东西。构造器则不会返回任何东西,你别无选择(new表达式确实放回了对新建对象的应用,但是构造器本身并没有任何返回值)。假如构造器具有返回值,并且允许人们自行选择返回类型,那么势必得让编译器知道该如何处理此返回值。
相关推荐
了解构造函数、this关键字以及对象的创建和初始化。 - **封装**:通过访问修饰符(public、private、protected)实现数据隐藏,提供公共接口进行交互。 - **继承**:子类继承父类,获取其属性和方法,实现代码复用...
综上所述,《Think in Java》这本书深入浅出地讲解了Java的核心概念和技术细节,包括构建器的特殊性质、`finalize()`方法在资源管理中的角色、`this`关键字的应用以及对象初始化的流程。通过对这些关键知识点的理解...
一个构造器可以调用同一个类的其他构造器来初始化对象,以简化代码并确保一致性。 8. **对象的比较**:Java中的equals()方法用于比较两个对象的内容是否相等,而hashCode()方法则与对象的唯一标识有关,常用于哈希...
7. 构造器与对象初始化 - 构造器:理解构造器的作用,以及如何创建带参数的构造器。 - this关键字:学习this指针的使用,以及在构造器中的应用。 - 初始化块:了解实例初始化块和类初始化块的使用。 8. 接口与...
构建器用于确保对象的正确初始化,同时介绍函数重载的概念。垃圾收集器的运作机制在此详细阐述,包括内存管理。此外,还讨论了成员初始化的细节,如自动成员初始化、指定成员初始化、初始化顺序和static初始化。 第...
3. **构造器与析构函数**:理解构造器在对象初始化时的作用,以及析构函数在对象销毁前执行的任务。 4. **访问修饰符**:掌握 public、private、protected 及默认的访问权限,了解其在类和成员上的应用。 5. **...
在解答中,你将看到如何声明、初始化和使用这些基本元素。 2. **类与对象**:Java中的所有事物都被视为对象,类是创建对象的蓝图。书中会涉及类的定义、构造函数、成员变量和方法、访问修饰符(public、private、...
子类可以使用`super()`关键字调用父类的构造器,确保父类的初始化过程得以执行。在创建子类实例时,子类的构造器通常会首先调用父类的构造器,然后再进行子类自身的初始化工作。 例如: ```java public class ...
1. 变量与数据类型:Java提供了基本数据类型(如int、double、char等)以及引用数据类型,理解变量的声明、初始化和使用是编程的基础。 2. 控制结构:包括条件语句(if、switch)、循环(for、while、do-while)和...
2. 构造函数与析构函数:构造函数在创建对象时自动调用,用于初始化对象;析构函数在对象销毁前调用,用于清理资源。 3. 函数重载与运算符重载:函数重载允许在同一作用域内使用相同名称但参数列表不同的函数;...
在C++编程中,首先,你需要理解基本的数据类型,如int、float、char等,以及如何声明和初始化变量。C++支持静态类型检查,这意味着在编译时必须为每个变量指定类型。同时,C++也提供了指针的概念,它是内存地址的...
6. **Monkey与People类**:`Monkey`类有一个构造器和`speak()`方法。`People`类继承`Monkey`,重写`speak()`方法,并添加`think()`方法。在主类中创建这两个类的对象并测试它们的功能。 7. **Human、Man和Woman类**...
内容涉及对象的演化、数据抽象、隐藏实现、初始化与清除、函数重载与缺省参数、输入输出流介绍、常量、内联函数、命名控制、引用和拷贝构造函数、运算符重载、动态对象创建、继承和组合、多态和虚函数、模板和包容器...
3. **构造函数和析构函数**:用于对象的初始化和清理工作,理解它们对于内存管理和对象生命周期至关重要。 4. **操作符重载**:C++允许你为已有的操作符赋予新的含义,使得代码更易读,表达更直观。 5. **动态内存...
3. **构造函数与析构函数**:C++中,构造函数用于初始化新创建的对象,而析构函数则在对象生命周期结束时执行清理工作。书中会解释它们的作用和用法,以及如何使用成员初始化列表和拷贝构造函数。 4. **模板**:...
《Think in C++》与《Effective C++》是C++编程领域的两本经典著作,对于想要深入理解并熟练掌握C++语言的程序员来说,这两本书是不可或缺的学习资源。 《Think in C++》由Bruce Eckel编写,是一本全面介绍C++语言...
内容涉及对象的演化、数据抽象、隐藏实现、初始化与清除、函数重载与缺省参数、输入输出流介绍、常量、内联函数、命名控制、引用和拷贝构造函数、运算符重载、动态对象创建、继承和组合、多态和虚函数、模板和包容器...