2012-10-10 117 views
3

对于我来说,我无法弄清楚为什么这个程序在Java 7中不起作用。我已经在使用Java 6时没有问题地运行它,但是只要我用Java 7运行它, ,它不起作用。与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,如果我按下按钮,它会打印出那句“成功”,直到我再次按下按钮。使用Java 7注册该按钮被按下并且状态值已更改为true,但从不打印短语“成功”。这是怎么回事?

回答

4

volatile添加到字段声明。

没有volatile,字段中的更改不保证在其他线程上可见。
特别是,JITter可以自由地相信该字段永远不会在主线程上发生变化,从而完全删除if

+1

非常感谢!就是这样。这是Java 7的一项新功能吗?我不得不承认,我对Java的知识完全是自学的,所以我可以对许多事情无知,但我从未见过这个词。 – user1630640

+0

@ user1630640:否;这可能是JITter的一个变化。如果你想做多线程开发,我推荐阅读Java Concurrency in Practice。如果没有,你应该坚持Swing工作者线程。多线程是_hard_。 – SLaks

0

当你展示的JFrame

frame.setVisible(true); 

Java的显示窗口,并停止在该行的执行。

您配置窗口关闭退出上:您关闭窗口后

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

该程序将终止。

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

+0

他已经在'init()'中做了这个。另外,'setVisible()'将_never_停止执行。该行只是防止主线程停止时JVM终止。他实际上并不需要它。 – SLaks

+0

如果我关闭了窗户,情况会如此,但我不必这样做。在初始化框架并添加了按钮(在init()方法中发生)后,接下来要处理的是while循环(只要我不关闭窗口)。基本上,当JFrame打开时,while循环会永久运行。我的问题是if语句在while循环中不起作用。 – user1630640