首页 文章

Java JVM HotSwap行为

提问于
浏览
0

我今天尝试了Javas Hotswap,它的工作非常好 . 在我的测试中,我偶然发现了一个相当奇怪的行为 . 这是我的代码:

public class Test extends JFrame implements ActionListener{

private JButton c;
private int f =1;
/**
 * @param args
 */
public static void main(String[] args) {
    Test t = new Test();
}

public Test(){
    this.setPreferredSize(new Dimension(800, 600));
    this.setDefaultCloseOperation(EXIT_ON_CLOSE);
    c = new JButton("Click");
    c.addActionListener(this);
    this.add(c);
    this.pack();
    this.setVisible(true);
}

@Override
public void actionPerformed(ActionEvent e) {
    c.setText(String.valueOf(f++));

}

}

注意接近结尾的 c.setText(String.valueOf(f++)); 行 . 如果我在程序运行时将其切换到 f-- ,我注意到在更改后第一次单击按钮时,该值仍在计数 . 然而,之后的点击正确计数 . 更换它时会发生同样的情况 .

我注意到的下一件事是:如果我将代码更改为: c.setText(String.valueOf(f+=1)); ,运行JVM并将其热交换为 c.setText(String.valueOf(f-=1)); ,直接应用更改,没有单击延迟 .

我现在的问题是:究竟是什么导致了这种行为? JVM代码级别 f++f+=1 之间有什么区别?

2 回答

  • 0

    在这段代码上使用javap:

    public static void main(String[] args) throws Exception {
        int i = 0;
        i++;
        System.out.println(i);
        i+=1;
        System.out.println(i);
    }
    

    回报

    0: iconst_0
      1: istore_1
      2: iinc          1, 1
      5: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
      8: iload_1
      9: invokevirtual #3                  // Method java/io/PrintStream.println:(I)V
     12: iinc          1, 1
     15: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
     18: iload_1
     19: invokevirtual #3                  // Method java/io/PrintStream.println:(I)V
     22: return
    

    ==>没有区别

  • 0

    你关闭了所有的优化吗?有quite a few不同tricks JIT compiler可以在幕后动态执行,因此生成的underlying code在执行期间会更改multiple times .

    使用actionPerformed()可以处理异步事件,即使没有热插拔问题,也可能使执行路径更加困难 .

    做同样的测试代码

    c.setText(String.valueOf(f++));
    

    但是在设置断点的大循环中进行,这样就可以用较少的运动部件测试变化 .

相关问题