1700441342
1700441343
//构造代码块,计算产生对象数量
1700441344
1700441345
numOfObjects++;
1700441346
1700441347
}
1700441348
1700441349
public Base(){
1700441350
1700441351
}
1700441352
1700441353
//有参构造调用无参构造
1700441354
1700441355
public Base(String_str){
1700441356
1700441357
this();
1700441358
1700441359
}
1700441360
1700441361
//有参构造不调用其他构造
1700441362
1700441363
public Base(int_i){
1700441364
1700441365
}
1700441366
1700441367
//返回在一个JVM中,创建了多少个实例对象
1700441368
1700441369
public static int getNumOfObjects(){
1700441370
1700441371
return numOfObjects;
1700441372
1700441373
}
1700441374
1700441375
}
1700441376
1700441377
这段代码是可行的吗?能计算出实例对象的数量吗?哎,好像不对呀,如果编译器把构造代码块插入到各个构造函数中,那带有String形参的构造函数可就有问题,它会调用无参构造,那通过它生成Base对象时就会执行两次构造代码块:一次是由无参构造函数调用构造代码块,一次是执行自身的构造代码块,这样的话计算可就不准确了,main函数实际在内存中产生了3个对象,但结果却会是4。不过真是这样的吗?Are you sure?我们运行一下看看结果:
1700441378
1700441379
实例对象数量:3
1700441380
1700441381
非常遗憾,你错了,实例对象的数量还是3,程序没有任何问题。奇怪吗?不奇怪,上一个建议是说编译器会把构造代码块插入到每一个构造函数中,但是有一个例外的情况没有说明:如果遇到this关键字(也就是构造函数调用自身其他的构造函数时)则不插入构造代码块,对于我们的例子来说,编译器在编译时发现String形参的构造函数调用了无参构造,于是放弃插入构造代码块,所以只执行了一次构造代码块—结果就是如此。
1700441382
1700441383
那Java编译器为什么会这么聪明呢?这还要从构造代码块的诞生说起,构造代码块是为了提取构造函数的共同量,减少各个构造函数的代码而产生的,因此,Java就很聪明地认为把代码块插入到没有this方法的构造函数中即可,而调用其他构造函数的则不插入,确保每个构造函数只执行一次构造代码块。
1700441384
1700441385
还有一点需要说明,读者千万不要以为this是特殊情况,那super也会类似处理了。其实不会,在构造代码块的处理上,super方法没有任何特殊的地方,编译器只是把构造代码块插入到super方法之后执行而已,仅此不同。
1700441386
1700441387
注意 放心地使用构造代码块吧,Java已经想你所想了。
1700441388
1700441389
1700441390
1700441391
[
上一页 ]
[ :1.700441342e+09 ]
[
下一页 ]