日期:2011-03-22 16:17:00 来源:本站整理
java构建器初始化[Java编程]
本文“java构建器初始化[Java编程]”是由七道奇为您精心收集,来源于网络转载,文章版权归文章作者所有,本站不对其观点以及内容做任何评价,请读者自行判断,以下是其具体内容:
可考虑用构建器履行初始化进程.这样便可在编程时得到更大的机动程度,因为我们可以在运行期调用办法和采纳行动,从而“现场”决意初始化值.但要注意这样一件事情:不可阻碍自动初始化的举行,它在构建器进入之前就会发生.因此,假定利用下述代码:
class Counter {
int i;
Counter() { i = 7; }
// . . .
那么i首先会初始化成零,然后变成7.关于全部基本范例以及对象句柄,这种情形都是成立的,此中包含在定义时已举行了明确初始化的那些一些.考虑到这个缘由,编译器不会试着逼迫我们在构建器任何特定的场所对元素举行初始化,大概在它们利用之前——初始化早已得到了保证(注释⑤).
⑤:相反,C++有自己的“构建器初始模块列表”,能在进入构建器主体之前举行初始化,并且它关于对象来说是强迫举行的.拜见《Thinking in C++》.
1. 初始化次序
在一个类里,初始化的次序是由变量在类内的定义次序决意的.即便变量定义大量遍及于办法定义的中间,那些变量仍会在调用任何办法之前得到初始化——乃至在构建器调用之前.比方:
在Card中,Tag对象的定义成心处处散布,以证明它们全城市在构建器进入大概发生其他任何事情之前得到初始化.除此之外,t3在构建器内部得到了重新初始化.它的输入后果以下://: OrderOfInitialization.java // Demonstrates initialization order. // When the constructor is called, to create a // Tag object, you'll see a message: class Tag { Tag(int marker) { System.out.println("Tag(" + marker + ")"); } } class Card { Tag t1 = new Tag(1); // Before constructor Card() { // Indicate we're in the constructor: System.out.println("Card()"); t3 = new Tag(33); // Re-initialize t3 } Tag t2 = new Tag(2); // After constructor void f() { System.out.println("f()"); } Tag t3 = new Tag(3); // At end } public class OrderOfInitialization { public static void main(String[] args) { Card t = new Card(); t.f(); // Shows that construction is done } } ///:~
Tag(1) Tag(2) Tag(3) Card() Tag(33) f()
因此,t3句柄会被初始化两次,一次在构建器调用前,一次在调用期间(第一个对象会被丢弃,所以它后来可被当作垃圾收掉).从表面看,这样做仿佛效率低下,但它能保证精确的初始化——若定义了一个过载的构建器,它没有初始化t3;同时在t3的定义里并没有规定“默许”的初始化方法,那么会产生什么后果呢?
2. 静态数据的初始化
若数据是静态的(static),那么一样的事情就会发生;假如它属于一个基本范例(主范例),并且未对其初始化,就会自动得到自己的尺度基本范例初始值;假如它是指向一个对象的句柄,那么除非新建一个对象,并将句柄同它衔接起来,不然就会得到一个空值(NULL).
假如想在定义的同时举行初始化,采纳的办法与非静态值表面看起来是相同的.但由于static值只有一个存储区域,所以无论成立多少个对象,都必定会碰到什么时刻对那个存储区域举行初始化的问题.下面这个例子可将这个问题说更清楚一些:
//: StaticInitialization.java // Specifying initial values in a // class definition. class Bowl { Bowl(int marker) { System.out.println("Bowl(" + marker + ")"); } void f(int marker) { System.out.println("f(" + marker + ")"); } } class Table { static Bowl b1 = new Bowl(1); Table() { System.out.println("Table()"); b2.f(1); } void f2(int marker) { System.out.println("f2(" + marker + ")"); } static Bowl b2 = new Bowl(2); } class Cupboard { Bowl b3 = new Bowl(3); static Bowl b4 = new Bowl(4); Cupboard() { System.out.println("Cupboard()"); b4.f(2); } void f3(int marker) { System.out.println("f3(" + marker + ")"); } static Bowl b5 = new Bowl(5); } public class StaticInitialization { public static void main(String[] args) { System.out.println( "Creating new Cupboard() in main"); new Cupboard(); System.out.println( "Creating new Cupboard() in main"); new Cupboard(); t2.f2(1); t3.f3(1); } static Table t2 = new Table(); static Cupboard t3 = new Cupboard(); } ///:~
Bowl答应我们查抄一个类的成立历程,而Table和Cupboard能成立散布于类定义中的Bowl的static成员.注意在static定义之前,Cupboard先成立了一个非static的Bowl b3.它的输出后果以下:
Bowl(1) Bowl(2) Table() f(1) Bowl(4) Bowl(5) Bowl(3) Cupboard() f(2) Creating new Cupboard() in main Bowl(3) Cupboard() f(2) Creating new Cupboard() in main Bowl(3) Cupboard() f(2) f2(1) f3(1)
static初始化只有在必要的时刻才会举行.假如不成立一个Table对象,并且永久都不引用Table.b1或Table.b2,那么static Bowl b1和b2永久都不会成立.但是,只有在成立了第一个Table对象之后(大概发生了第一次static拜候),它们才会成立.在那今后,static对象不会重新初始化.
初始化的次序是首先static(假如它们还没有由前一次对象成立历程初始化),接着是非static对象.大家可从输出后果中找到呼应的证据.
在这里有必要总结一下对象的成立历程.请考虑一个名为Dog的类:
(1) 范例为Dog的一个对象初次成立时,大概Dog类的static办法/static字段初次拜候时,Java注释器必须找到Dog.class(在事前设好的类途径里搜索).
(2) 找到Dog.class后(它会成立一个Class对象,这将在背面学到),它的全部static初始化模块城市运行.因此,static初始化仅发生一次——在Class对象初次载入的时刻.
(3) 成立一个new Dog()时,Dog对象的构建进程首先会在内存堆(Heap)里为一个Dog对象分配充足多的存储空间.
(4) 这种存储空间会清为零,将Dog中的全部基本范例设为它们的默许值(零用于数字,以及boolean和char的等价设定).
(5) 举行字段定义时发生的全部初始化城市履行.
(6) 履行构建器.正如第6章将要讲到的那样,这实际大概要求举行相当多的操作,分外是在触及担当的时刻.
3. 明确举行的静态初始化
Java答应我们将其他static初始化工作划分到类内一个特别的“static构建从句”(有时也叫作“静态块”)里.它看起来象下面这个模样:
class Spoon { static int i; static { i = 47; } // . . .
固然看起来象个办法,但它实际只是一个static关键字,背面跟随一个办法主体.与其他static初始化一样,这段代码仅履行一次——初次生成那个类的一个对象时,大概初次拜候属于那个类的一个static成员时(即便从未生成过那个类的对象).比方:
//: ExplicitStatic.java // Explicit static initialization // with the "static" clause. class Cup { Cup(int marker) { System.out.println("Cup(" + marker + ")"); } void f(int marker) { System.out.println("f(" + marker + ")"); } } class Cups { static Cup c1; static Cup c2; static { c1 = new Cup(1); c2 = new Cup(2); } Cups() { System.out.println("Cups()"); } } public class ExplicitStatic { public static void main(String[] args) { System.out.println("Inside main()"); Cups.c1.f(99); // (1) } static Cups x = new Cups(); // (2) static Cups y = new Cups(); // (2) } ///:~
在标志为(1)的行内拜候static对象c1的时刻,或在行(1)标志为注释,同时(2)行不标志成注释的时刻,用于Cups的static初始化模块就会运行.若(1)和(2)都被标志成注释,则用于Cups的static初始化进程永久不会发生.
4. 非静态实例的初始化
针对每个对象的非静态变量的初始化,Java 1.1供应了一种近似的语法格局.下面是一个例子:
//: Mugs.java // Java 1.1 "Instance Initialization" class Mug { Mug(int marker) { System.out.println("Mug(" + marker + ")"); } void f(int marker) { System.out.println("f(" + marker + ")"); } } public class Mugs { Mug c1; Mug c2; { c1 = new Mug(1); c2 = new Mug(2); System.out.println("c1 & c2 initialized"); } Mugs() { System.out.println("Mugs()"); } public static void main(String[] args) { System.out.println("Inside main()"); Mugs x = new Mugs(); } } ///:~
大家可看到实例初始化从句:
它看起来与静态初始化从句极端类似,只是static关键字从里面消逝了.为支持对“匿名内部类”的初始化(拜见第7章),必须采取这一语法格局.{ c1 = new Mug(1); c2 = new Mug(2); System.out.println("c1 & c2 initialized"); }
以上是“java构建器初始化[Java编程]”的内容,如果你对以上该文章内容感兴趣,你可以看看七道奇为您推荐以下文章:
本文地址: | 与您的QQ/BBS好友分享! |
- ·上一篇文章:<b>java的数组初始化</b>
- ·下一篇文章:java规定初始化
- ·中查找“java构建器初始化”更多相关内容
- ·中查找“java构建器初始化”更多相关内容
评论内容只代表网友观点,与本站立场无关!
评论摘要(共 0 条,得分 0 分,平均 0 分)
查看完整评论