web-dev-qa-db-ja.com

ローカル変数は内部クラス内でアクセスされます(Java)

コードをコンパイルした後、2つのエラーが発生しました。

エラーは:

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's Name");
        JTextField input = new JTextField("",10);

        JLabel l2 = new JLabel("Choose Your Child's 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);
    }

}

このエラーを解決するにはどうすればよいですか?

18
Roubie

宣言する必要があります

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

そして

JComboBox c_age = new JComboBox(age);

このような:

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

final JComboBox c_age = new JComboBox(age);

つまり、inputc_age 変わることはできない:

内部クラスで使用されているが宣言されていないローカル変数は、必ず内部クラスの本体の前に割り当てる必要があります。

Java言語仕様、 セクション-8.1.3内部クラスとそれを含むインスタンス からの説明==

16
edwardsmatt

変数をfinalとして宣言すると、エラーが解決されますが、私によると、問題の適切な解決策ではありません。同様の問題がここで議論されました ここ を見て理解を深めることができます。

あなたの問題の解決策では、より良い解決策を得ることができるそれらを使用することにより、メソッドを定義することができます。ヒントは、次のように読むことができます 匿名内部クラス内の非最終ローカル変数にアクセスする方法

内部クラスの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's Name");
            final JTextField input = new JTextField("",10);

            JLabel l2 = new JLabel("Choose Your Child's 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);
        }

    }
2
Sean Kleinjung

finalを追加すると柔軟性が大幅に失われるため、次のことをお勧めします。とにかく推奨されるアクセサメソッドを作成します。しかし、これはオブジェクトを処理するときにほとんど役立ちますが、あなたの場合はすべてが静的です。したがって、この答えはあなたの特定の状況に当てはまらない可能性がありますが、エラーメッセージをグーグルで検索するとこの結果が上位の結果として得られるため、ほとんどの場合に当てはまる代替策だと思います(静的メソッドからすべてを行うよりもオブジェクトを使用する方が一般的です)。ここにも存在する必要があります。

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;
    }
}
1
11684

JTextFieldという名前の入力がmainメソッド内で宣言されました。あなたはおそらく次のようなことをするべきです:

  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.
      }

  }

そうすれば、内部クラス内の入力への参照で問題が発生しません。

0

アクセスしている2つの変数finalを宣言する必要があります:inputc_age

これを実行したくない場合は、新しいアドホッククラスではなく、適切なクラスを作成して、コンストラクターでパラメーターとして渡すか、(JavaでGUIを操作するときにこれを行いました)コンストラクターでオブジェクトを取得し、それらをローカルで使用できるようにするリスナークラス。その後、その場でインスタンス化します。

0
slezica

入力変数とc_age変数は、メソッドの実行が完了すると消えます。最終的なものでない限り、ローカル内部クラス内でこれらの変数を使用することはできません。

0
Ammu

メインクラスに一時変数を作成しました(例: 'tempString')。問題の原因となっている変数に設定できます。そう:

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's 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();
    }
}
0
Luke Alderton