关于变量在方法中声明的内部类中的可见性的一些疑问

时间:2013-11-12 17:37:01

标签: java actionlistener inner-classes

我对如何使用此方法有以下疑问:

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 的方法,它有一些输入参数,包括 String id 参数。

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

ActionListener内部类中,声明处理click事件的 actionPerformed()方法,在此方法结束时调用 showSection( id)方法传递给 id 参数id,它似乎与 createToolbarButton()输入参数相同。

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

是不是?为什么?这对我来说似乎很陌生

TNX

安德烈

2 个答案:

答案 0 :(得分:1)

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

如果您认为此行为很奇怪并且您不希望这样,那么请不要使用内部类。请改用普通的第一级课程。

答案 1 :(得分:1)

  

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

绝对 - 你可以看到传递给方法的所有局部变量参数,只要一个声明它们final(正如你所做的那样)。

  

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

这是没有构造函数的匿名类的设计结果。这种隐式捕获本地和参数的能力使您可以编写不需要匿名类来构造的代码。

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