Java编程思想学习笔记(八)
第五章 初始化和清理
”不安全“的编程方式逐渐成为编程代价高昂的主因之一。
初始化和清理正是涉及安全的两个问题,初始化涉及到程序或者组件的正常使用,清理不当则可能导致资源(尤其是内存)用尽。Java提供了构造器和垃圾回收器来解决这两类问题。
5.1用构造器确保初始化
假想为编写的每一个类都定义一个initialize()方法,在使用其对象之前需要用户去调用这个方法。Java的做法是通过提供构造器,类的设计者可确保每个对象都会得到初始化,创建对象时,若其类中有构造器,Java会在对象创建之前自动调用相应的构造器,这样就确保了初始化工作的进行。
和C++相同,Java中的构造器采用和类相同的名称,创建对象时,使用new关键字之后,会为对象分配存储空间,并且调用相应的构造器。同时,由于要和类名保持一致,构造器方法的首字母不必严格小写。
不接受任何参数的构造器称为默认构造器(无参构造器),假设我们定义了一个接受一个参数的构造器,同时这个构造器是类中唯一的构造器,那么编译器将不会允许使用任何其他方式来创建对象。
尽管看不到,但是Java的初始化和创建是捆绑在一起的。
构造器是一种特殊类型的方法,因为他没有返回值,这和返回值类型为void是不同的,构造器不会返回任何东西。
5.2方法重载
(方法名相同,接受的参数列表的类型不同)
大多数编程语言(尤其是C)要求每个方法都有独一无二的标识符,例如假设你用print()显示了整数,那么这个方法绝对不能用于显示浮点数。
但是在Java中,构造器是强制重载方法名的另一个原因,因为在很多情景下,我们需要多种创建对象的方式,但是前面说过构造器的名字应该与类名一致,这就必须要用到方法重载。
程序编写者写了若干个具有相同名字的方法,Java区分这些方法的标准就是这些方法的参数列表,这也意味着重载方法必须有自己独一无二的参数列表。这里的不同不限于参数的个数、类型,甚至参数的顺序也可以用来区分不同的重载函数,但是不推荐这么做,这样会让代码变得难以维护。
涉及基本类型的重载:基本类型可以从一个较小的类型自动提升到一个较大的类型,这个过程涉及到重载时,有可能会产生一些混淆。
实参小于形参:简单来说就是如果传入的数据类型小于方法声明的形参类型,那么实参的数据类型会自动提升,char比较特殊,若无法找到恰好接受char类型参数的方法,那么会直接把char提升至int型。
实参大于形参:若传入的实参较大,就得通过类型转换进行窄化转换,否则编译器会报错(窄化转换涉及到信息丢失的风险,需要由程序员显式地写在代码里)。
以返回值区分重载方法,不行:因为有时候方法调用并不会显式地用到方法的返回值,那么编译器就无从得知你到底要调用那个方法,所以说,使用返回值区分重载方法是行不通的。
5.3默认构造器
若在定义类的时候没有特意写构造器,那么编译器会自动帮你创建一个,但是如果程序员编写了 一个构造器(就算是无参的)那么编译器就不会再创建默认的构造器,相应的,如果你编写了一个含参的构造器,并且在创建对象的时候还使用无参的调用,那么编译器就会报错。
5.4this关键字
为了能够用简便的、面向对象的语法来编写代码,也即“发送消息给对象”,编译器暗自把所操作对象的引用作为第一个参数传递给方法。
若我们想在方法的内部获得当前对象的引用(也就是编译器隐式传入的引用,这是没有标识符的),那么可以使用this关键字。
this只能在方法内部使用,表示对“调用该方法的对象的引用”,this的用法和其他的引用并无区别,但是要注意的是,若是在方法中调用同一个类的另外的方法,那么不必使用this,直接调用即可。
常用的情景是在最后要返回当前对象的引用,可以使用return this;这种写法的好处是方便在一条语句中对一个对象进行多次操作(类似于传递性的、流水线的操作)。
5.4.1在构造器中调用构造器:有了this关键字之后,我们可以实现在一个构造器中调用另一个构造器的操作,以避免重复代码。通常情况下的this关键字都是指“这个对象”,并且表示对这个对象的引用,若我们对this添加了参数列表,那么就具有了不同的含义,就可以在构造器中通过this(参数列表)的形式来调用其他的构造器。需要注意的是:使用this调用的构造器在一层嵌套中只能调用一个,并且必须放在最起始处,否则会报错;除了在构造器中之外,不允许在其他位置调用构造器。
5.4.2static的含义:static(静态)方法就是没有this的方法。在static方法的内部不能调用非静态方法,反过来是可以的。(这个是之前上C++课一直没听懂的())
static方法的用法很像全局方法,但是Java本身是禁止全局方法的,static方法具有全局函数的语义,使用static方法时由于不存在this,所以不是通过向对象发送消息的方式来完成的,这也是有人质疑static方法不是面向对象的方法的原因(但是这和我又有什么关系呢)
2.14上传 读完5.4
P120