与Java 7不兼容

3

我真的想不出来为什么这个程序在Java 7中不能正常运行。使用Java 6时,我已经毫无问题地运行了它,但是一旦在Java 7上运行,它就不能工作。

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;

public class HelloWorld implements ActionListener {

JButton button;
boolean state;

public HelloWorld(){
    init();
    state = false;
    System.out.println("state - "+state);

    while (true){
        if (state == true){
            System.out.println("Success");
        }
    }
}

private void init(){
    JFrame frame = new JFrame();
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    button = new JButton("Button");
    button.addActionListener(this);
    frame.add(button);
    frame.pack();
    frame.setVisible(true);
}

@Override
public void actionPerformed(ActionEvent e) {
    JButton source = (JButton)e.getSource();

    if (source == button){
        state = !state;
        System.out.println("state - "+state);
    }
}

/**
 * @param args the command line arguments
 */
public static void main(String[] args) {
    new HelloWorld();
}

}

使用Java 6,如果我按下按钮,它将打印出短语“Success”,直到我再次按下按钮。使用Java 7注册按钮被按下并且状态值已更改为true,但短语“Success”从未被打印。发生了什么?

2个回答

4
在字段声明中添加 volatile
如果没有使用 volatile,则不能保证在其他线程上可见字段的更改。
特别地,JITter 可以自由地认为该字段在主线程上永远不会更改,从而允许完全删除 if

1
非常感谢!就是这个了。这是Java 7的新功能吗?我必须承认,我的Java知识完全是自学的,所以可能对很多东西都不了解,但我从未见过这个术语。 - user1630640
@user1630640:不是的;这可能是JITter的变化。如果你想进行多线程开发,我建议阅读《Java并发实践》。如果不是,你应该坚持使用Swing工作线程。多线程编程很难。 - SLaks

0

当你显示JFrame时

 frame.setVisible(true); 

Java代码展示窗口并在此行停止执行。

您已配置窗口在关闭时退出:

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

当你关闭窗口后,该程序将终止。

因此,在init()调用之后的代码将永远不会被执行。


他已经在init()中完成了那个操作。此外,setVisible()永远不会停止执行。该行代码只是防止主线程停止时JVM终止。实际上,他根本不需要它。 - SLaks
如果我关闭窗口,那就是真的了,但我不必这样做。在初始化框架并添加按钮之后(这发生在init()方法中),下一个要处理的事情是while循环(只要我不关闭窗口)。基本上,当JFrame打开时,while循环会永久运行。我的问题是,在while循环中if语句没有起作用。 - user1630640

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接