Подтвердить что ты не робот

Доступ к локальной переменной осуществляется внутри внутреннего класса (java)

После компиляции кода я получил две ошибки.

Ошибки:

1.

  local variable input is accessed within inner class; 
  needs to be declared final
     String name = input.getText();

2.

  local variable c_age is accessed within inner class; 
  needs to be declared final
     Object child_age = c_age.getSelectedItem();

Это мой код:

import javax.swing.*;
import java.awt.event.*;

public class GUI
{
    public static void main(String[] args)
    {
        JFrame frame = new JFrame("Try GUI");
        JLabel l1 = new JLabel("Please Enter Your Child Name");
        JTextField input = new JTextField("",10);

        JLabel l2 = new JLabel("Choose Your Child Age");
        String[] age = {"Age","1","2","3","4","5","6"};
        JComboBox c_age = new JComboBox(age);

        JButton button = new JButton("Search");

        JTextArea result = new JTextArea();
        JScrollPane extend_area = new JScrollPane(result);

        button.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent ae)
            {
                String name = input.getText();
                Object child_age = c_age.getSelectedItem();
            }
        });

        JPanel panel = new JPanel();
        panel.add(l1);
        panel.add(input);
        panel.add(l2);
        panel.add(c_age);
        panel.add(button);
        panel.add(extend_area);
        frame.add(panel);
        frame.setSize(350,350);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }

}

Как я могу решить эту ошибку?

4b9b3361

Ответ 1

Вам нужно объявить

JTextField input = new JTextField("",10);

и

JComboBox c_age = new JComboBox(age);

вот так:

final JTextField input = new JTextField("",10);

final JComboBox c_age = new JComboBox(age);

Это означает, что input и c_age не могут измениться:

Любая локальная переменная, используемая, но не объявленный во внутреннем классе, должен быть определенно назначенных до тело внутреннего класса.

Объяснение, взятое из Спецификации языка Java, Раздел - 8.1.3 Внутренние классы и экземпляры Enclosing

Ответ 2

Если вы объявите переменные в качестве окончательного, то он решит ваши ошибки, но, по моему мнению, это не хорошее решение проблемы. Подобная проблема обсуждалась здесь, вы можете посмотреть здесь для лучшего понимания.

В решении вашей проблемы вы можете определить методы, используя их, вы можете получить лучшее решение. Для подсказки вы можете прочитать Как получить доступ к не конечной локальной переменной внутри анонимного внутреннего класса

Ответ 3

Любая переменная, которую вы используете внутри метода actionPerformed вашего внутреннего класса, должна быть объявлена ​​окончательной. Попробуйте следующее:

import javax.swing.*;
import java.awt.event.*;

    public class GUI
    {
        public static void main(String[] args)
        {
            JFrame frame = new JFrame("Try GUI");
            JLabel l1 = new JLabel("Please Enter Your Child Name");
            final JTextField input = new JTextField("",10);

            JLabel l2 = new JLabel("Choose Your Child Age");
            String[] age = {"Age","1","2","3","4","5","6"};
            final JComboBox c_age = new JComboBox(age);

            JButton button = new JButton("Search");

            JTextArea result = new JTextArea();
            JScrollPane extend_area = new JScrollPane(result);

            button.addActionListener(new ActionListener()
            {
                    public void actionPerformed(ActionEvent ae)
                    {
                        String name = input.getText();
                        Object child_age = c_age.getSelectedItem();


                    }
            });

            JPanel panel = new JPanel();
            panel.add(l1);
            panel.add(input);
            panel.add(l2);
            panel.add(c_age);
            panel.add(button);
            panel.add(extend_area);
            frame.add(panel);
            frame.setSize(350,350);
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setVisible(true);
        }

    }

Ответ 4

Как добавление final устраняет большую гибкость, я хотел бы предложить следующее: создать метод доступа, который в любом случае поощряется. Но это в основном полезно при работе с объектами, тогда как в вашем случае все статично. Таким образом, этот ответ может не применяться к вашей конкретной ситуации, но поскольку поиск в Google для вашего сообщения об ошибке дает этот вопрос в качестве верхнего результата, я думаю, что альтернатива, применимая в большинстве случаев (использование объектов более распространено, чем выполнение всего от статического метода) также должны присутствовать здесь.

public class MyClass extends MySuperClass {
    private MyPropertyClass aProperty;

    public MyClass() {
        new JButton().setActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                // aProperty.aMethod(); -- Bang! That should be final, the compiler says.
                getMyProperty().aMethod(); // -- Everything okay, works fine, no compiler complaints.
            }
        });
    }

    public getMyProperty() {
        return aProperty;
    }
}

Ответ 5

Именованный вход JTextField был объявлен внутри основного метода. Вероятно, вы должны сделать что-то вроде этого:

  public class GUI{

      //declare all your components here e.g.

      JTextField input;

      public static void main(String args[]){
              new GUI();
      }

      public GUI(){
          //instantiate components here
          input = new JTextField();
          //and so on.
      }

  }

Таким образом, ссылка на ввод внутри внутреннего класса не даст никаких проблем.

Ответ 6

Вы должны объявить final две переменные, которые вы используете: input и c_age.

Если вы не хотите этого делать, вы можете либо создать новый правильный класс (а не рекламный), либо передать его в качестве параметров в конструкторе, либо (я сделал это при работе с GUI в Java ) создайте класс слушателя, который принимает объекты в своем конструкторе и делает их доступными локально, затем ad-hoc создает экземпляр этого файла.

Ответ 7

Входная переменная и переменная c_age исчезают после завершения выполнения метода. Вам не разрешат использовать эти переменные внутри локальных внутренних классов, если они не являются окончательными.

Ответ 8

Я только что создал временный var в основном классе, например, "tempString", а затем он может быть установлен в var, который вызывает проблему. Итак:

tempString = myString

таким образом я могу вызвать tempString без каких-либо проблем. Проверьте мой пример ниже:

// Create my temp var here
private String tempUrl;

// my function here
public void updatePage(String url)
{
    // Can use 'url' here because it not within inner class
    if(!url.equals(""))
    {
        // Set 'tempUrl' to 'url' so I can use it without problem
        tempUrl = url;

        // My inner class that used to cause the problem
        backgroundUpdate = new Thread(new Runnable()
        {
            // From here on I use 'tempUrl' to solve the problem
            public void run()
            {
                // Do something with 'tempUrl' here (where 'url' used to be used)
            }
        });

        backgroundUpdate.start();
    }
}