1. 将一个float或double值造型成整数值后,总是将小数部分“砍掉”,不作任何进位处理。
2.
同样的规则亦适用于while:
(1) 简单的一个continue会退回最内层循环的开头(顶部),并继续执行。
(2) 带有标签的continue会到达标签的位置,并重新进入紧接在那个标签后面的循环。
(3) break会中断当前循环,并移离当前标签的末尾。
(4) 带标签的break会中断当前循环,并移离由那个标签指示的循环的末尾。
3.
在这两种情况下,我们都必须人工中断程序,所以会发现Math.random()“似乎”永远都不会产生0.0或1.0。但这只是一项实验而已。若想到0和1之间有2的128次方不同的双精度小数,所以如果全部产生这些数字,花费的时间会远远超过一个人的生命。当然,最后的结果是在Math.random()的输出中包括了0.0。或者用数字语言表达,输出值范围是[0,1)。
4.
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章将要讲到的那样,这实际可能要求进行相当多的操作,特别是在涉及继承的时候。
5.
大家可能会疑惑这个循环什么时候会停下来,因为内部没有任何改变Chair.f值的语句。然而,finalize()进程会改变这个值,直至最终对编号47的对象进行收尾处理。
每次循环过程中创建的String对象只是属于额外的垃圾,用于吸引垃圾收集器——一旦垃圾收集器对可用内存的容量感到“紧张不安”,就会开始关注它。
运行这个程序的时候,提供了一个命令行自变量“before”或者“after”。其中,“before”自变量会调用System.gc()方法(强制执行垃圾收集器),同时还会调用System.runFinalization()方法,以便进行收尾工作。这些方法都可在Java 1.0中使用,但通过使用“after”自变量而调用的runFinalizersOnExit()方法却只有Java 1.1及后续版本提供了对它的支持(注释③)。注意可在程序执行的任何时候调用这个方法,而且收尾程序的执行与垃圾收集器是否运行是无关的。