见下文:

/这是我的主/

package br.com.general;

public class Main {

    public static void main(String[] args) {

        Wind w = new Wind();
        w.start();

        while(true){
            //System.out.printf("%b\n", w.button());
            if(w.button()){
                System.out.printf("xx %b\n", w.button());
            }
        }

    }

}


/这是我的带有一个按钮的JFrame窗口/

package br.com.general;

import javax.swing.JButton;
import javax.swing.JFrame;

public class Wind extends JFrame{

    private static final long serialVersionUID = 1L;
    Act a = new Act();

    public Wind() {
        setDefaultCloseOperation(EXIT_ON_CLOSE);

        JButton B = new JButton("on");

        getContentPane().setLayout(null);

        B.setBounds(10, 10, 50, 30);
        B.addActionListener(a);

        add(B);
        setSize(100, 100);
    }

    public void start() {
        setVisible(true);
    }
    public boolean button(){
        return(a.button());
    }
    public void buttonOk(){
        a.zero();
    }
}


/ *最后是我的按钮的ActionListener * /

package br.com.general;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class Act implements ActionListener {
    boolean s;
    public void actionPerformed(ActionEvent ae) {
        s = true;

    }
    public boolean button(){
        return(s);
    }
    public void zero(){
        s = false;
    }
}


如果运行,则可以看到该行不通,但是如果在主行中删除了“ //”并启用行“ System.out.printf(“%b \ n”,w.button() );“它开始起作用...
为什么?有人可以帮助我吗?

最佳答案

这个问题问得好!在理想情况下,无论第一个System.out.println(…)是否已注释掉,您的代码都将毫无问题地运行。

问题在于Java优化了您的代码,并且并不总是检索s类中Act标志的当前值。

为了规避这种优化(在这种情况下是错误的)优化,可以使用volatile修饰符:volatile boolean s;。这要求JVM始终从内存中检索实际值并防止对其进行缓存,请参见Atomic Access in The Java Tutorials

07-24 09:38
查看更多