Java 为什么我的对象会看到构造函数中没有给它的变量?
我有以下代码。这是“正确的”,我不理解:Java 为什么我的对象会看到构造函数中没有给它的变量?,java,variables,constructor,visibility,Java,Variables,Constructor,Visibility,我有以下代码。这是“正确的”,我不理解: private static void updateGUI(final int i, final JLabel label) { SwingUtilities.invokeLater( new Runnable() { public void run() { label.setText("You have " + i + " seconds.");
private static void updateGUI(final int i, final JLabel label) {
SwingUtilities.invokeLater(
new Runnable() {
public void run() {
label.setText("You have " + i + " seconds.");
}
}
);
}
我创建Runnable类的一个新实例,然后在此实例的run
方法中使用变量label
和I
。它是有效的,但我不明白它为什么有效。为什么所考虑的对象会看到这些变量的值
根据我的理解,代码应该是这样的(而且是错误的):
因此,我会将I
和标签
变量提供给构造函数,以便对象可以访问它们
顺便说一下,在
updateGUI
中,我在I
和标签之前使用final
。我想我使用了final
,因为编译器需要它。但是我不明白为什么。编译器为您完成这项工作(因为您不能在匿名类中使用构造函数)。这背后的基本原理是,标签
位于内部类的可视区域内。您可以访问对象的字段,也可以创建非匿名的内部类来访问最终参数和局部变量。因为可以看到外部类的所有变量。
第二个示例的问题是,Runnable接口的实现者应该有一个没有参数的构造函数。final
封闭方法中声明的变量可以由该方法中的匿名内部类访问。如果将参数设置为非最终参数,则会看到编译器发出抱怨
不能在匿名内部类中声明构造函数。人们有时通过编写初始化程序块来解决这个问题
new Runnable() {
{ /* this code is executed */ }
public void run() {
// ...
}
};
我认为不能访问非最终变量的理由是,如果创建匿名内部类对象,然后更改非最终变量,那么匿名内部类是否应该使用更新的值?当函数终止执行并且变量被销毁时,它如何管理这种情况?如果它只能使用最终变量,那么语义是明确的:它将获取最终变量值的快照 之所以可以这样做是因为final关键字。这是一个解释原因的链接 实际上,理由是updateGUI方法可能在可运行对象被销毁之前终止。事实上,最终变量的值作为额外的隐藏参数传递给内部类构造函数,并由内部类存储在隐藏(最终)属性中。如果您使用javap
@Stephen查看字节码,您可以看到这一点,真不错。谢谢你的提示。相关问题:
new Runnable() {
{ /* this code is executed */ }
public void run() {
// ...
}
};