有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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

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

第一部分,主要是使用SwingUIBuilder创建的编辑掉的评论/导入

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);
}
}

第二部分是listener类

// 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);**
    }
}

它抱怨无法从类型屏幕对非静态方法changeLabel(String)进行静态引用。然而,如果我用窗口代替屏幕,它就找不到对象。这让我非常困惑。我对代码的理解是,main方法创建了一个名为window的Screen对象,初始化时它也创建了一个XListener对象。为什么它认为Actuple被执行的方法是静态的?我知道我遗漏了一些基本的东西,我一直在遵循java的“轨迹”,只是不明白


共 (5) 个答案

  1. # 1 楼答案

    window是在main中创建的匿名Runnable子类中的run方法中的一个局部变量。你当然不能在XListener.actionPerformed中引用它

    Java并不认为actionPerformed方法是静态的-它说changeLabel是非静态的,但您试图^{]访问它,就好像它是静态的一样,这里:

    Screen.changeLabel(foo);
    

    不管actionPerformed是静态的还是非静态的,关键是您需要对Screen实例进行引用,以便调用changeLabel方法。否则就像问“这个人有多高?”除非你指定你谈论的是哪个人,否则这是没有意义的

    如果您发现静态/非静态令人困惑,我强烈建议您暂时不要使用用户界面。编写一些简单的控制台应用程序,创建一些对象,调用它们的方法等。熟悉语言,最好是一些核心库(如集合和IO)然后您将能够进入有时令人生畏的用户界面世界,并且至少知道语言级别的情况

  2. # 2 楼答案

    方法changeLabel是一个实例方法,但是您试图使用<;的静态方法语法调用它;类名>&书信电报;方法名称>;。您需要获取对Screen对象的引用才能调用此方法

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

    XListener(Screen screen, String setString)
        ...
        this.screen=screen;
        ...
        }
    
  3. # 3 楼答案

    您已经定义了一个名为changeLabel的非静态方法,但随后尝试在类外(即屏幕)访问它。changeLabel(),因为它不是静态方法,所以无法执行此操作。您首先需要实例化Screen,然后从您创建的实例中调用此方法(或通过实例等,重点是非静态方法需要从对象中访问,而不是直接从类中访问)

  4. # 4 楼答案

    XListener类需要一个对象来调用它。调用Screen.changeLabel(foo)将尝试在类屏幕上调用静态方法。您需要将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
    }
    
  5. # 5 楼答案

    当操作发生时,应传入对要影响的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实例,可以正确调用该方法