2011-04-13 5 views
18

코드를 컴파일 한 후 두 개의 오류가 발생했습니다.로컬 변수가 내부 클래스 (java) 내에서 액세스됩니다.

오류는 다음과 같습니다

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

1

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

2

내 코드입니다

어떻게이 오류를 해결할 수

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); 
    } 

} 
?

답변

16

당신은

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 변경할 수 없음을 의미합니다 :

inputc_age : Java 언어 사양에서 가져온

설명, Section - 8.1.3 Inner Classes and Enclosing Instances

+0

문제 solved.but 당신 explainahope 이해할 수 없다면 더 많이 줄 수 ... 감사합니다 많은 에드워드 – Roubie

+0

발췌 및 자바 언어 사양에 대한 링크를 첨부, 그 도움이되기를 바랍니다 ... – edwardsmatt

+3

최종 사용자가 필요합니다 내부 클래스/클로저에 의해 사용될 때 변수를 변경할 수 없습니다. 그것에 대해 생각해보십시오 : 최종으로 표시되지 않은 경우 내부 클래스 참조는 선언 옆에있는 모든 코드를 수행 할 수 있으므로 동시성 문제를 피하기 위해 최종 것으로 표시해야하며 구문이이를 시행합니다. –

0

input이라는 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

정적 변수가 아닌 변수를 정적 컨텍스트에서 참조 할 수 없습니다. – Roubie

+0

주된 방법은 정적 컨텍스트입니다. 제 예제에서와 같이 클래스의 인스턴스를 인스턴스화하여 중단해야합니다. main 메소드의 다양한 코드가 생성자에 있어야합니다. –

0

당신은 당신이 accesing하고 final 두 변수를 선언해야합니다.

이렇게하고 싶지 않으면 새로운 적절한 클래스를 만들고 (ad-hoc이 아닌) 적절한 생성자를 생성자의 매개 변수로 전달하거나 (또는 ​​GUI로 작업 할 때이 작업을 수행 할 수 있습니다. Java)는 생성자에서 객체를 가져 와서 로컬에서 사용할 수있게 만드는 리스너 클래스를 만들고 그 인스턴스를 ad-hoc 인스턴스로 만듭니다.

2

당신이 최종 선언해야합니다 당신의 내부 클래스의 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); 
     } 

    } 
+0

최종 선언해야하는 이유를 설명 할 수 있습니까? – Seth

0

메소드 실행이 완료된 후 입력 변수와 c_age 변수가 사라집니다. 이 변수는 final이 아니면 로컬 내부 클래스에서 사용할 수 없습니다.

5

If you declare the variables as an final then it will solve your errors but according to me its not the good solution for the problem. Similar problem has discussed here you can have a look here for more understanding.

In solution to yours problem you can have define methods by using them you can get better solution. For hint you can read How to access non-final local variable inside anonymous inner class

+0

다른 방법으로 입력 및 c_age 변수를 문제를 해결할 정적 인스턴스 변수로 선언 할 수 있습니다. –

0

메인 클래스에 'tempString'과 같은 임시 var를 만든 다음 문제의 원인이되는 var로 설정할 수 있습니다.그래서 :

tempString = myString 

그런 식으로 나는 전혀 문제없이 tempString을 호출 할 수 있습니다. 아래에있는 내 예를 확인 : final 유연성을 많이 빼앗아 추가로

// 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(); 
    } 
} 
1

을, 나는 다음과 같은 제안하고 싶습니다 : 어쨌든 권장되는 접근 방법을 만들 수 있습니다. 그러나 이것은 객체를 처리 할 때 주로 유용하지만 모든 경우 정적입니다. 따라서이 대답은 사용자의 특정 상황에 적용되지 않을 수도 있지만 오류 메시지가 정상적인 결과로이 질문에 대한 검색 결과를 얻을 수 있기 때문에 대부분의 경우 적용 할 수있는 대안을 생각합니다 (정적 메서드에서 모든 작업을 수행하는 것보다 일반적입니다) 여기에도 있어야합니다.

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; 
    } 
} 
관련 문제