在内部类(java)中访问局部变量
我编译代码后出现了两个错误 错误为: 1.在内部类(java)中访问局部变量,java,actionlistener,inner-classes,final,Java,Actionlistener,Inner Classes,Final,我编译代码后出现了两个错误 错误为: 1. local variable input is accessed within inner class; needs to be declared final String name = input.getText(); local variable c_age is accessed within inner class; needs to be declared final Object child_age
local variable input is accessed within inner class;
needs to be declared final
String name = input.getText();
local variable c_age is accessed within inner class;
needs to be declared final
Object child_age = c_age.getSelectedItem();
2.
local variable input is accessed within inner class;
needs to be declared final
String name = input.getText();
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);
}
}
如何解决此错误?名为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.
}
}
final JTextField input = new JTextField("",10);
final JComboBox c_age = new JComboBox(age);
这样,对内部类中输入的引用就不会出现问题。您需要声明
JTextField input = new JTextField("",10);
及
像这样:
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.
}
}
final JTextField input = new JTextField("",10);
final JComboBox c_age = new JComboBox(age);
这意味着input
和c\u age
不能更改:
任何局部变量,已使用但未使用
在内部类中声明的
在比赛前明确分配
内部类的主体
根据Java语言规范的解释,您必须声明正在访问的两个变量:
input
和c\u age
如果您不想这样做,那么您可以创建一个新的适当类(不是临时类)并将其作为参数传递到构造函数中,或者(我在Java中使用GUI时就是这样做的)创建一个侦听器类,该类接受构造函数中的对象并使它们在本地可用,然后特别实例化它。您在内部类的
actionPerformed
方法中使用的任何变量都需要声明为final。请尝试以下操作:
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);
}
}
方法执行完成后,输入变量和c_age变量消失。除非是最终的,否则不允许在本地内部类中使用这些变量 如果你将变量声明为最终变量,那么它将解决你的错误,但根据我的说法,这不是解决问题的好办法。类似的问题已经在这里讨论过了,你们可以看看,以获得更多的理解 在解决您的问题时,您可以定义方法,通过使用它们,您可以得到更好的解决方案。你可以读到一些提示
我刚刚在主类中创建了一个临时变量,例如“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();
}
}
由于添加
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;
}
}
问题已解决。但我不理解您的解释。希望您能提供更多…非常感谢Edward附加了Java语言规范的摘录和链接,我希望这有帮助…需要final,以便用户在内部类/闭包使用变量时无法更改变量。想想看:如果它没有标记为final,内部类引用可以完成声明旁边的一些代码所能做的一切,因此您必须将它标记为final以避免并发问题,并且语法强制执行这一点。我有一个错误:不能从静态上下文引用非静态变量。主要方法是静态上下文。您必须通过实例化类的实例(如我的示例中所示)来打破它。然后,主方法中的各种代码应该进入构造函数。换句话说,您可以将输入和c_年龄变量声明为静态实例变量,这将解决您的问题。您能否解释为什么需要将其声明为final?