Java 为什么将ActionListener添加到JButton时,这两个类似的for循环会有不同的结果?
最初我有一个JFrame,它有3个按钮:哪个按钮0单击时打印0,按钮1打印1,依此类推:Java 为什么将ActionListener添加到JButton时,这两个类似的for循环会有不同的结果?,java,for-loop,jbutton,Java,For Loop,Jbutton,最初我有一个JFrame,它有3个按钮:哪个按钮0单击时打印0,按钮1打印1,依此类推: JFrame jframe=new JFrame(); jframe.getContentPane().setLayout(new GridLayout(3,1)); for(int i=0;i<3;i++){ final int j=i; JButton jbutton=new JButton(""+j); jframe.getContentPane().add(jbutto
JFrame jframe=new JFrame();
jframe.getContentPane().setLayout(new GridLayout(3,1));
for(int i=0;i<3;i++){
final int j=i;
JButton jbutton=new JButton(""+j);
jframe.getContentPane().add(jbutton);
jbutton.setPreferredSize(new Dimension(100,100));
jbutton.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
System.out.println(""+j);
}
});
}
jframe.setVisible(true);
jframe.pack();
jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
由于最后一个变量,我想减少1行,因此重构for循环如下:
JFrame jframe=new JFrame();
jframe.getContentPane().setLayout(new GridLayout(3,1));
for(final int[] arr={0};arr[0]<3;arr[0]++){
JButton jbutton=new JButton(""+arr[0]);
jframe.getContentPane().add(jbutton);
jbutton.setPreferredSize(new Dimension(100,100));
jbutton.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
System.out.println(""+arr[0]);
}
});
}
jframe.setVisible(true);
jframe.pack();
jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
但是这次所有按钮都打印3,即使按钮索引仍然是0,1,2,原因是什么?在第二个程序中,您将相同的变量传递给所有三个按钮。然后在每次迭代中增加变量的值。因此,所有三个按钮的值都会更新 我举个简单的例子
class Resource{
int a = 10;
}
class A{
Resource r;
}
class B{
public static void main(String args[]){
Resource r = new Resource();
A o1 = new A();
o1.r = r;
A o2 = new A();
o2.r = r;
o1.r.a = 20;
System.out.println(o1.r.a); // prints 20
System.out.println(o2.r.a); // prints 20 too
}
}
循环结束后,i[0]为3。ActionListener都持有对i的引用,并将读取i[0]的相同值,即3
如果要更正此问题,请将i[0]的值指定给一个局部最终变量,并将其指定给输出,如:
for(int[] arr = {0}; arr[0] < 3; arr[0]++) {
final int val = arr[0];
...
jbutton.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
System.out.println("" + val);
}
});
}
正确的方法是获取事件源,然后不需要final int 为什么要对final int[]arr={0}使用数组;arr[0]arr[0]+。。。循环完成时,arr[0]处的值是多少?
for(int[] arr = {0}; arr[0] < 3; arr[0]++) {
final int val = arr[0];
...
jbutton.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
System.out.println("" + val);
}
});
}
public static void main(String [] args)
{
JFrame jframe=new JFrame();
jframe.getContentPane().setLayout(new GridLayout(3,1));
for(int i=0;i<3;i++){
JButton jbutton=new JButton(""+ i);
jframe.getContentPane().add(jbutton);
jbutton.setPreferredSize(new Dimension(100,100));
jbutton.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
JButton myButton = (JButton)e.getSource();
System.out.println(""+ myButton.getText());
}
});
}
jframe.setVisible(true);
jframe.pack();
jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}