某些时候,对于一个类来说,跟踪其创建出来的实例个数会非常用有,其典型实现是通过让它的构造器递增一个私有静态域来完成的。在下面的程序中,Creature类展示了这种技巧,而Creator类对其进行了操练,将打印出已经创建的Creature实例的数量。那么,这个程序会打印出什么呢? public class Creator { public static void main(String[] args) { for (int i = 0. i < 100. i ) Creature creature = new Creature(). System.out.println(Creature.numCreated()). } }
class Creature { private static long numCreated = 0. public Creature() { numCreated . } public static long numCreated() { return numCreated. } }
这是一个捉弄人的问题。该程序看起来似乎应该打印100,但是它没有打印任何东西,因为它根本就不能编译。如果你尝试着去编译它,你就会发现编译器的诊断信息基本没什么用处。下面就是javac打印的东西: Creator.java:4: not a statement Creature creature = new Creature(). ^ Creator.java:4: ’.’ expected Creature creature = new Creature(). ^
一个本地变量声明看起来像是一条语句,但是从技术上说,它不是;它应该是一个本地变量声明语句(local variable declaration statement)[JLS 14.4]。Java语言规范不允许一个本地变量声明语句作为一条语句在for、while或do循环中重复执行[JLS 14.12-14]。一个本地变量声明作为一条语句只能直接出现在一个语句块中。(一个语句块是由一对花括号以及包含在这对花括展中的语句和声明构成的。) 有两种方式可以订正这个问题。最显而易见的方式是将这个声明至于一个语句块中: for (int i = 0. i < 100. i ) { Creature creature = new Creature(). }
然而,请注意,该程序没有使用本地变量creature。因此,将该声明用一个无任何修饰的构造器调用来替代将更具实际意义,这样可以强调对新创建对象的引用正在被丢弃: for (int i = 0. i < 100. i ) new Creature().