由构建器担保初始化
对付要领的建设,可将其想象成为本身写的每个类都挪用一次initialize()。这个名字提醒我们在利用工具之前,应首先举办这样的挪用。但不幸的是,这也意味着用户必需记着挪用要领。在Java中,由于提供了名为“构建器”的一种非凡要领,所以类的设计者可包管每个工具城市获得正确的初始化。若某个类有一个构建器,那么在建设工具时,Java会自动挪用谁人构建器——甚至在用户绝不知觉的环境下。所以说这是可以包管的!
接着的一个问题是如何定名这个要领。存在两方面的问题。第一个是我们利用的任何名字都大概与规划为某个类成员利用的名字斗嘴。第二是由于编译器的责任是挪用构建器,所以它必需知道要挪用是哪个要领。C++采纳的方案看来是最简朴的,且更有逻辑性,所以也在Java里获得了应用:构建器的名字与类名沟通。这样一来,可担保象这样的一个要了解在初始化期间自动挪用。
下面是带有构建器的一个简朴的类(若执行这个措施有问题,请参考第3章的“赋值”小节)。
//: SimpleConstructor.java // Demonstration of a simple constructor package c04; class Rock { Rock() { // This is the constructor System.out.println("Creating Rock"); } } public class SimpleConstructor { public static void main(String[] args) { for(int i = 0; i < 10; i++) new Rock(); } } ///:~
此刻,一旦建设一个工具:
new Rock();
就会分派相应的存储空间,并挪用构建器。这样可担保在我们经手之前,工具获得正确的初始化。
请留意所有要领首字母小写的编码法则并不合用于构建器。这是由于构建器的名字必需与类名完全沟通!
和其他任何要领一样,构建器也能利用自变量,以便我们指定工具的详细建设方法。可很是利便地窜改上述例子,以便构建器利用本身的自变量。如下所示:
class Rock { Rock(int i) { System.out.println( "Creating Rock number " + i); } } public class SimpleConstructor { public static void main(String[] args) { for(int i = 0; i < 10; i++) new Rock(i); } }
操作构建器的自变量,我们可为一个工具的初始化设定相应的参数。举个例子来说,假设类Tree有一个构建器,它用一个整数自变量标志树的高度,那么就可以象下面这样建设一个Tree工具:
tree t = new Tree(12); // 12英尺高的树
若Tree(int)是我们独一的构建器,那么编译器不会答允我们以其他任何方法建设一个Tree工具。
构建器有助于消除大量涉及类的问题,并使代码更易阅读。譬喻在前述的代码段中,我们并未看到对initialize()要领的明晰挪用——那些要领在观念上独立于界说内容。在Java中,界说和初始化属于统一的观念——两者缺一不行。
构建器属于一种较非凡的要领范例,因为它没有返回值。这与void返回值存在着明明的区别。对付void返回值,尽量要领自己不会自动返回什么,但仍然可以让它返回另一些对象。构建器则差异,它不只什么也不会自动返回,并且基础不能有任何选择。若存在一个返回值,并且假设我们可以自行选择返回内容,那么编译器几多要知道如何对谁人返回值作什么样的处理惩罚。