【发布时间】:2020-08-06 15:32:32
【问题描述】:
我正在学习 Java 中的内部类,但我遇到了与外部方法中的变量引用有关的问题。例如,我有一个源代码可以统计排序过程中调用compareTo()方法的次数:
int counter = 0;
Date[] dates = new Date[100];
for(int i = 0; i < dates.length; i++)
{
dates[i] = new Date()
{
public int compareTo(Date other)
{
counter++;
return super.compareTo(other);
}
};
}
Arrays.sort(dates);
System.out.println(counter + " comparisons");
在执行源码时,可以看到counter++的使用存在错误。为了解决这个问题,有人告诉我应该这样改:
int[] counter = new int[1];
Date[] dates = new Date[100];
for(int i = 0; i < dates.length; i++)
{
dates[i] = new Date()
{
public int compareTo(Date other)
{
counter[0]++;
return super.compareTo(other);
}
};
}
Arrays.sort(dates);
System.out.println(counter[0] + " comparisons");
我很困惑这两个代码有什么区别,这个错误的原因和解决方法是什么?
【问题讨论】:
-
您只能在匿名类和 lambda 表达式中使用最终/有效最终变量。使用
int[]是一种解决方法(这可能适合您的情况,也可能不适合您的情况),因为变量counter被编译器识别为final,但其中的元素仍然可以更改。相关:Why are only final variables accessible in anonymous class?。另见atomic variables。 -
@user 我很抱歉,但是如何将
int counter转换为int[] counter将计数器更改为实际上是最终的? -
转换为数组并不能使其有效地最终化。在第一个示例中,您使用
counter++更改了counter的值,因此它不是最终的。但是,在第二个示例中,您并没有更改变量counter本身,而是更改了其中的元素,因此counter实际上是最终的。如果你不确定一个变量是否是有效的最终变量,请将其标记为final并查看编译器是否抱怨
标签: java class oop inner-classes