Java另一个静态/非静态问题

时间:2011-08-17 20:08:41

标签: java static-methods

好的,使用Eclipse IDE并在静态/非静态问题上绊倒。我想我理解它,但不完全,这是代码。

第一部分,主要是使用swing UI构建器创建的。 编辑了评论/导入

public class Screen {

private JFrame frame;
public JLabel lblNewLabel;
public static void main(String[] args) {
    EventQueue.invokeLater(new Runnable() {
        public void run() {
            try {
                Screen window = new Screen();
                window.frame.setVisible(true);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    });
}

public Screen() {
    initialize();
}

void initialize() {
    XListener listenItem = new XListener("Woot"); // creates listen object

    frame = new JFrame();
    frame.setBounds(100, 100, 450, 300);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.getContentPane().setLayout(null);

    JLabel lblNewLabel = new JLabel("New label");
    lblNewLabel.setBounds(193, 154, 56, 16);
    frame.getContentPane().add(lblNewLabel);

    JButton btnNewButton = new JButton("New button");
    btnNewButton.setBounds(163, 73, 97, 25);
    frame.getContentPane().add(btnNewButton);
    btnNewButton.addActionListener(listenItem); // attaches it to listen object
}
void changeLabel(String setString) {
    lblNewLabel.setText(setString);
}
}

第二部分是听众类

// creates class for listen item
public class XListener implements ActionListener {
    String foo;
    XListener(String setString) {
        foo = setString;
    }
    public void actionPerformed(ActionEvent btnNewButton) {
        **Screen.changeLabel(foo);**
    }
}

它抱怨无法从类型Screen中对非静态方法changeLabel(String)进行静态引用。然而,如果我使用窗口,而不是屏幕,它找不到对象。这让我非常困惑。我理解代码的方法是main方法创建一个名为window的Screen对象,在初始化时也会创建一个XListener对象。为什么它认为actionPerformed方法是静态的?我知道我缺少一些基本的东西,而且我一直在关注java'trail'而只是没有得到它。

5 个答案:

答案 0 :(得分:4)

您应该在操作发生时传递对您想要影响的Screen对象的引用:

// creates class for listen item
public class XListener implements ActionListener {
    String foo;
    Screen myScreen;

    XListener(String setString, Screen scr) {
        foo = setString;
        myScreen = scr;
    }
    public void actionPerformed(ActionEvent btnNewButton) {
        myScreen.changeLabel(foo);
    }
}

然后,像这样初始化你的监听器:

XListener listenItem = new XListener("Woot", this);

您必须执行此操作,因为changeLabel()方法是Screen类的实例方法,但您尝试像static方法一样访问它。通过访问正确的Screen实例,您可以正确调用该方法。

答案 1 :(得分:1)

您的XListener类需要一个对象来调用它。调用Screen.changeLabel(foo)将尝试在类Screen上调用静态方法。您需要将一个Screen对象传递到XListener类。

public class XListener implements ActionListener {
    String foo;
    Screen myScreen; // added
    XListener(String setString, Screen theScreen) {
        foo = setString;
        myScreen= theScreen; // added
    }
    public void actionPerformed(ActionEvent btnNewButton) {
        screen.changeLabel(foo); // fixed
    }
}

然后更改你的init方法:

void initialize() {
    XListener listenItem = new XListener("Woot",this); // creates listen object

    // rest below
}

答案 2 :(得分:1)

方法changeLabel是一个实例方法,但您尝试使用< Class Name>。< Method Name>的静态方法语法调用它。您需要获取对Screen对象的引用才能调用此方法。

解决它的一种方法可能是将这样的对象传递给侦听器的构造函数,如下所示:

XListener(Screen screen, String setString)
    ...
    this.screen=screen;
    ...
    }

答案 3 :(得分:1)

windowrun中创建的匿名Runnable子类中main方法中的本地变量。你当然不能在XListener.actionPerformed内引用它。

Java并不认为actionPerformed方法是静态的 - 它说changeLabel是非静态的,但你正试图访问它就好像它是静态的< em>来自 actionPerformed,此处:

Screen.changeLabel(foo);

actionPerformed是否为静态无关紧要 - 重点是您需要引用Screen实例才能调用{{1} }} 方法。否则就像问“这个人有多高?” - 除非你指定你正在谈论的人,否则没有意义。

如果您发现静态/非静态混淆,我会强烈建议您暂时保留用户界面。编写一些简单的 console 应用程序,这些应用程序创建一些对象,调用它们的方法等。熟悉语言,理想情况下是一些核心库(例如集合和IO)。 然后你将能够进入有时令人生畏的用户界面世界,至少知道语言级别发生了什么。

答案 4 :(得分:0)

您已经定义了一个名为changeLabel的非静态方法,但是您尝试从类中访问它,即您无法执行的Screen.changeLabel(),因为它不是静态方法。首先需要实例化Screen,然后从你创建的实例中调用此方法(或者通过实例等,点是非静态方法需要从Object访问,而不是直接从类中访问)。 / p>