局部内部类和匿名内部类访问final的局部变量---一个元素的数组

     在Java的内部类中,匿名内部类和局部内部类在访问局部变量时,局部变量只能是final的,在我的另一篇文章中分析了原因:为什么局部内部类和匿名内部类只能访问final的局部变量?


   虽然final保证了局部变量与在局部类内建立的拷贝保持一致,但有时final限制却显得不太方便。在学习《java核心卷术 卷1》这本书时,里面给出了一种改善这种限制的方案:


       例如:假设想更新在一个封闭作用域内的计数器。这里想要统计一下在排序过程中调用compareTo方法的次数:

public class Demo {
	public static void main(String[] args) {
		int counter = 0;
		Date[] dates = new Date[100];
		for (int i = 0; i < 100; i++) {
			dates[i] = new Date() {
				/*
				 * 下面相当于建立了Date类的一个匿名子类,并添加了新的compareTo方法
				 */
				public int compareTo(Date other) {
					counter++;//Error:Cannot refer to a non-final variable counter inside an inner class defined in a different method
					return super.compareTo(other);
				}
			};
		}
		Arrays.sort(dates);
		System.out.println("次数:" + counter);
	}
}

       由于清楚的知道counter需要进行更新,所以counter不能设置为final。由于Integer对象是不可变的,也不能用Integer去代替它。补救的方法是使用一个长度为1的数组:

public class Demo {
	public static void main(String[] args) {
		final int[] counter = new int[1];
		Date[] dates = new Date[100];
		for (int i = 0; i < 100; i++) {
			dates[i] = new Date() {
				public int compareTo(Date other) {
					counter[0]++;
					return super.compareTo(other);
				}
			};
		}
		Arrays.sort(dates);
		System.out.println("次数:" + counter[0]);
	}
}
       数组变量虽然被定义为final的,但这仅仅表示不可以让这个数组变量引用另外一个数组,数组中的数据元素仍然可以被改变。
 

       至于编译器是怎么编译匿名内部类的,我们可以反编译生成的.class文件,如下:


局部内部类和匿名内部类访问final的局部变量---一个元素的数组_第1张图片


      可以看到,匿名内部类确实是extends了Date类,并扩展了新的compareTo方法,也即相当于下面的形式:

public class Demo {
	public static void main(String[] args) {
		Date[] dates = new Date[100];
		for (int i = 0; i < 100; i++) {
			dates[i] = new myDate();
		}
		Arrays.sort(dates);
		System.out.println(myDate.getCounter());
	}

}

class myDate extends Date {

	private static int counter = 0;

	@Override
	public int compareTo(Date anotherDate) {
		counter++;
		return super.compareTo(anotherDate);
	}

	public static int getCounter() {
		return counter;
	}
}
       此时就可以看到,由于只需要对compareTo方法进行小小的修改,并且不需要知道myDate类的存在,使用匿名内部类会更加的简洁,处理起来也会更加的方便。



你可能感兴趣的:(javaSE)