为什么我的内部类不能看到我的外部类对象?

时间:2012-04-17 18:55:22

标签: java

import javax.swing.*;
import javax.swing.event.*;

public class NewGUIStuff{
    public static void main(String args[]){
        NewGUIStuff gui = new NewGUIStuff();
        gui.go();
    }

    class handlesListListeners implements  ListSelectionListener{
        public void valueChanged(ListSelectionEvent lse){
            list.setVisibleRowCount(4);
        }
    }
    public void valueChanged(ListSelectionEvent lse){

    }
    public void go(){
        JFrame frame = new JFrame();
        JPanel panel = new JPanel();
        JList list;

        String[] aList = {"alpha","beta","gamma","delta","epsilon","zeta","eta","theta"};
        list = new JList(aList);
        list.addListSelectionListener(new handlesListListeners());
        JScrollPane scroller = new JScrollPane(list);
        scroller.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
        scroller.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);

        frame.setContentPane(scroller);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(300,300);
        frame.setVisible(true);
    }
}

所以我的问题是,如果内部类可以看到它们的外部类变量和对象,为什么内部类handlesListListeners可以看到我在list中创建的NewGUIStuff对象外层?

5 个答案:

答案 0 :(得分:2)

答案是,“你的内心阶级可以看到外层阶级”,这不是你的问题。

您的问题是NewGUIStuff类没有内部类要查看的任何成员字段。您声明的list变量是go方法的本地变量。

public class NewGUIStuff {
    JList list; //this is a member field

    ...

    public void go() {
        ...
        JList list; //this is a local variable
        ...
    }
}

答案 1 :(得分:2)

因为list对象在go()方法的范围内,而不是NewGUIStuff类的范围。列表对象只能在同一方法中“看到”。

答案 2 :(得分:2)

非静态内部类可以看到外部类实例变量以及它们被包围的那些局部变量(想想闭包),如果它们被声明为final(在匿名内部类的情况下) )。那些非静态内部类具有对编译器插入的外部this的隐式引用,这就是它们如何看到外部类的成员变量。包含匿名类的最终局部变量将隐式传递给编译器将为您生成的构造函数,并存储在内部类本身的最终成员字段中。

在你的情况下,我看到你期望看到一个局部变量在一个完全不同的词汇上下文中定义,你的内部类是不知道的。将它转换为外部类成员变量,内部类将看到它。

答案 3 :(得分:1)

您的list变量是方法go()的本地变量。如果您希望它可见,则需要将其设为NewGUIStuff的实例字段。像这样:

public class NewGUIStuff {

    private JList list = new JList(); // Member of outer class so in scope from handlesListListeners

    public static void main(String args[]) {
        NewGUIStuff gui = new NewGUIStuff();
        gui.go();
    }

    class handlesListListeners implements  ListSelectionListener {

        public void valueChanged(ListSelectionEvent lse) {
            list.setVisibleRowCount(4);
        }
    }
}

答案 4 :(得分:1)

这是因为listgo()函数中的局部变量。它超出了handlesListListeners类的范围。

如果list是外部类的实例变量,那么内部类就能看到它。或者,您也可以将内部类设置为go()函数的本地类,这意味着list现在在范围内:

void go() {
    final JList list = ...
    list.addListSelectionListener(new ListSelectionListener() {
        public void valueChanged(ListSelectionEvent event) {
            // list is now in scope
            list.setVisibleRowCount(4);
        }
    });
}

请注意,list必须声明为最终(如果以这种方式使用)。