1

今日はJavasHotswapを試しましたが、非常にうまく機能しています。私のテスト中に、私はかなり奇妙な振る舞いに出くわしました。これは私のコードです:

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

4

2 に答える 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

==>違いはありません

于 2012-04-10T15:59:09.827 に答える
0

すべての最適化をオフにしましたか?JITコンパイラが舞台裏で動的に実行できるさまざまなトリックがかなりあるため、結果として得られる基になるコード実行中に複数回変更されます。

actionPerformed()を使用すると、ホットスワップの問題がなくても実行パスの追跡が困難になる可能性のある非同期イベントを処理します。

同じテストコードを実行します

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

ただし、ブレークポイントが設定された大きなループ内で実行してください。そうすれば、可動部品を減らしてバリエーションをテストできます。

于 2012-04-10T15:59:42.523 に答える