Java中如何在JButton的ActionListener内部访问外部定义的对象
报错原因
Java 要求匿名内部类访问的外部局部变量必须是final修饰的,或者是有效不可变(赋值后没有二次修改)的。你的代码中to变量先赋值为null,后续在try代码块中又做了二次赋值,不满足有效不可变的要求,因此编译报错。
解决方案
以下提供三种常用的解决方式,可根据你的代码场景选择:
方案1:将变量提升为类成员变量
把to从方法内的局部变量改为所在类的成员变量,匿名内部类可以直接访问类的成员变量,不受final限制。
示例代码:
// 把to定义为类的成员变量 private testobject to; // 你的业务方法内的代码 File inputfile = new File("./input.txt"); try { Scanner inputscan = new Scanner(inputfile); String text1 = inputscan.nextLine(); String text2 = inputscan.nextLine(); to = new testobject(text1,text2); inputscan.close(); } catch (Exception e) { System.err.println(e); } JButton btnSave = new JButton("Save"); btnSave.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { // 增加非空判断避免空指针异常 if (to != null) { to.setSomething("test"); } } });
方案2:使用AtomicReference包装对象
如果不想修改成员变量,可使用AtomicReference包装目标对象,包装类本身声明为final即可,内部存储的对象可以任意修改。
示例代码:
File inputfile = new File("./input.txt"); final AtomicReference<testobject> toRef = new AtomicReference<>(); try { Scanner inputscan = new Scanner(inputfile); String text1 = inputscan.nextLine(); String text2 = inputscan.nextLine(); toRef.set(new testobject(text1,text2)); inputscan.close(); } catch (Exception e) { System.err.println(e); } JButton btnSave = new JButton("Save"); btnSave.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { testobject to = toRef.get(); if (to != null) { to.setSomething("test"); } } });
方案3:调整赋值逻辑让变量满足有效不可变
将文件读取实例化的逻辑封装为独立方法,让to只完成一次赋值,满足有效不可变的要求:
// 独立封装的对象加载方法 private testobject loadTestObject() { File inputfile = new File("./input.txt"); try { Scanner inputscan = new Scanner(inputfile); String text1 = inputscan.nextLine(); String text2 = inputscan.nextLine(); testobject result = new testobject(text1,text2); inputscan.close(); return result; } catch (Exception e) { System.err.println(e); return null; } } // 业务方法内的代码 final testobject to = loadTestObject(); JButton btnSave = new JButton("Save"); btnSave.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { if (to != null) { to.setSomething("test"); } } });
内容的提问来源于stack exchange,提问作者copy14
相关产品推荐
相关产品推荐

