【问题标题】:local variable iteration defined in an enclosing scope must be final or effectively final在封闭范围内定义的局部变量迭代必须是最终的或有效的最终
【发布时间】:2020-12-29 01:58:02
【问题描述】:

每当我尝试编译程序时,都会收到错误消息“在封闭范围内定义的局部变量迭代必须是最终的或有效的最终”。有谁知道如何解决这一问题?代码还没有完成,所以有些地方可能看起来不合适。

public static void go(purchase joe) {
    JFrame frame = new JFrame();
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    SpinnerNumberModel NumberImput = 
            new SpinnerNumberModel(1.00,0.00,null,1.00);
    int iteration = 0;
    JSpinner spinner = new JSpinner(NumberImput);
    JLabel label = new JLabel("Please enter the price of the Item.");
    JButton button = new JButton("Press here to continue");
       button.addActionListener(new ActionListener(){  
            public void actionPerformed(ActionEvent e){  
                switch (iteration) {
                case 0:
                    joe.setPrice((double)NumberImput.getNumber());
                    label.setText("Plese enter the amount that you are buying");
                    NumberImput.setValue(1.00);
                    iteration += 1;
                    break;
                case 1:
                    joe.setAmount((int)NumberImput.getNumber());
                    label.setText("Plese enter the amount that you are buying");
                    break;
                
                
                
                }
            }  
            });  
    frame.setLayout(new FlowLayout());
    frame.add(label);
    frame.add(spinner);
    frame.add(button);
    frame.setSize(600, 500);
    frame.setExtendedState(JFrame.MAXIMIZED_BOTH); 
    frame.setVisible(true);
    joe.setPrice((double)NumberImput.getNumber());
}

【问题讨论】:

  • 您在匿名类实现中使用方法级变量,例如“joe”、标签。作为一个动作监听器,你永远不知道它什么时候会被执行,因此我们在类范围内的任何变量的使用都应该是最终的。

标签: java swing


【解决方案1】:

您正在使用iteration += 1;。这是对局部变量的赋值。 现在 ActionListener 对象的寿命比局部变量长; actionPerformed 可能会在方法的调用消失后被调用。

出于这个原因,Java 虚拟机向 ActionListener 添加了一个新变量 iteration,这是一个副本。为了防止分配给局部变量 iteration 会使 other iteration 过时,语言决定局部变量必须是常量,而不是分配给“有效地最终”。

AtomicInteger iteration = new AtomicInteger();

... iteration.getAndIncrement();

但是,由于稍后会调用 actionPerformed,所以只需删除 iteration。 你可以在 ActionListener 中使用一个字段。

    button.addActionListener(new ActionListener() {  
        int iter;

        @Override
        public void actionPerformed(ActionEvent e) {  
            switch (iter) {
            case 0:
                joe.setPrice(NumberImput.getNumber().doubleValue());
                label.setText("Please enter the amount that you are buying");
                NumberImput.setValue(1.00);
                iter++;
                break;
            case 1:
                joe.setAmount(NumberImput.getNumber().intValue());
                label.setText("Please enter the amount that you are buying");
                break;
            }
        }  
    });  

关于风格:始终使用@Override,因为您会在类似情况下捕捉到拼写错误。

        @Override
        public void actionPerformed(ActionEvent e){  

使用numberInput;以小写字母开头的变量、字段和方法。

【讨论】:

    猜你喜欢
    • 2017-08-28
    • 2019-10-28
    • 2019-03-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-27
    相关资源
    最近更新 更多