对方法中声明的内部类中变量的可见性有一些疑问



我对此方法的工作原理有以下疑问:

protected JButton createToolbarButton(String name, final String id, final JPanel panel)
{   
    JButton button = new JButton(name);     // Create a new JButton
    // If the passed Jpanel named "panel" exist, add this to the JPanel named content (the CardLayout container)
    if (panel != null)
        content.add(panel, id);
    else
        button.setEnabled(false);       // Otherwise disable this button
    button.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e)
        {
            //System.out.println(panel.getClass());
            if (panel instanceof SchedulingPanel)
                ((SchedulingPanel)panel).getTasksSettings().fireSettingsUpdated();
            else if (panel instanceof EventsPanel)
                ((EventsPanel)panel).refreshPanel();
            else if (panel instanceof ConfigurationPanel)
                ((ConfigurationPanel)panel).refreshPane();
            showSection(id);
        }
    });
    return button;
}

我有一个名为CreateToolbarButton的方法,它有一些输入参数,包括字符串id参数。

正如您在此方法中看到的,我将一个 ActionListener 内部类添加到我的 JButton 对象(处理此按钮上的单击事件)。

在这个 ActionListener 内部类中,它被声明为处理单击事件的 actionPerformed() 方法,在此方法结束时,它调用 showSection(id) 方法,将 id 参数传递给 id,该参数似乎是 createToolbarButton() 输入参数的相同参数。

所以在我看来,在我的 ActionListener 内部类中,我也可以看到容器方法的参数和变量(createToolbarButton())

对吗?为什么?这对我来说似乎有点奇怪

安德里亚

是的,您确实有可见性。 这些变量是最终的这一事实保证了这一点。换句话说,由于它们不会更改,因此内部类不会尝试引用在方法createToolbarButton完成时可能死亡的变量。

如果您认为这种行为很奇怪并且不希望这样做,请不要使用内部类。 请改用通用的第一级类。

在我看来,在我的ActionListener内部类中,我也可以看到容器方法(createToolbarButton())的参数和变量,对吗?

绝对 - 您确实可以看到传递给该方法的所有局部变量参数,只要将它们声明为final(就像您所做的那样)。

为什么?这对我来说似乎有点奇怪

这是匿名类没有构造函数的设计结果。这种隐式捕获局部变量和参数的功能使您可以编写不需要匿名类具有构造函数的代码。

但实际上,您的匿名类确实有一个构造函数。由于从方法实现主体引用final需要捕获的所有局部变量都将成为此不可见构造函数的参数。编译器隐式传递这些参数以及对封闭类this的引用,然后在引用这些属性的方法的主体中插入对这些捕获属性的引用。

最新更新