【问题标题】:Changing a variable value inside a void method to be used outside in Java?更改 void 方法内的变量值以在 Java 外部使用?
【发布时间】:2017-02-15 16:06:16
【问题描述】:

我是 Java 新手。我搜索了这个,但没有找到明确的答案。

有没有办法在 void 方法中更改预定义变量的值,并通过另一个 void 方法使用新值?

我需要什么: 在 Eclipse WindowBuilder 中,单击按钮应该会更改在该按钮之外定义的变量的值。 所以我可以在单击另一个按钮时使用新值。但是,当我单击另一个按钮时,会使用最初定义的值,而不是更改后的值一个。

更新:示例代码:

private void initialize() {
        frame = new JFrame();
        frame.setBounds(100, 100, 450, 300);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().setLayout(null);
        String x = "0";

        JButton btn1 = new JButton("Button 1");
        btn1.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                String x = "1";
                textField1.setText(x);              
            }
        });
        btn1.setBounds(102, 134, 89, 23);
        frame.getContentPane().add(btn1);

        JButton btn2 = new JButton("Button 2");
        btn2.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                textField2.setText(x);
            }
        });
        btn2.setBounds(232, 134, 89, 23);
        frame.getContentPane().add(btn2);

        textField1 = new JTextField();
        textField1.setBounds(159, 85, 86, 20);
        frame.getContentPane().add(textField1);
        textField1.setColumns(10);

        textField2 = new JTextField();
        textField2.setColumns(10);
        textField2.setBounds(159, 179, 86, 20);
        frame.getContentPane().add(textField2);
    }

所以这里x 被初始化为"0"。单击按钮 1,将 x 更改为 "1"。然后,单击按钮 2,给出初始化值 "0" 而不是 "1"

【问题讨论】:

  • 如果这是一个静态或实例变量,是的,如果是本地的,不是。编辑:请用单词和/或小代码定义预定义变量
  • 如果它不是原始且不可变的 - 请显示代码
  • 欢迎来到 Stack Overflow!请查看我们的SO Question Checklist 以帮助您提出一个好问题,从而得到一个好的答案。
  • 如果您提供代码会很有帮助。话虽如此,您要访问方法外的变量,类级别的变量在类内的所有级别都可以访问。希望对您有所帮助!
  • 你必须在你的类定义中在这个方法之外定义你的变量。所以你可以用你的按钮来使用它。

标签: java eclipse windowbuilder


【解决方案1】:

在您的代码中,您使用的是局部变量 x

JButton btn1 = new JButton("Button 1");
    btn1.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            final String x = "1";
            textField1.setText(x);              
        }
    });

这个变量不会存在于你声明的内部类方法ActionListener.actionPerformed之外。

您需要在符合您需要的范围内声明您的变量。

在这种情况下,您需要使用变量实例(请参阅下面的注释),因此在方法 initialize 之外声明 String x 成为实例的一部分。

String x; //instance variable to be shared
private void initialize() {
    ...
    JButton btn1 = new JButton("Button 1");
    btn1.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            x = "1";
            textField1.setText(x);              
        }
    });

    JButton btn2 = new JButton("Button 2");
    btn2.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            textField2.setText(x);
        }
    });

}

注意:你不能简单地把它放在 initialize 方法中,因为你需要把它作为 final 放在一个内部类中使用,但是你正在为它设置一个值,所以它是不可能的你的情况。

PS:

请注意,您正在跟踪 initialize 方法的 String x

String x = "0";

JButton btn1 = new JButton("Button 1");
btn1.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent e) {
        String x = "1";
        textField1.setText(x);              
    }
});

在click方法中,这不会使用当前为"0"x,它将是一个完全不同的实例(即使有相同的名称)。所以你也需要删除那个声明,因为你会隐藏我刚刚声明的实例变量。

What are Shadow Variables in Java

但简短的描述是:

如果存在另一个同名且范围更近的变量,则该变量将被隐藏

展示这种阴影的一个小例子是

public class Main {

    String x = "a";
    public static void main(String[] args) {
        new Main();
    }

    public Main(){
        System.out.println(x); //"a"
        String x = "b";
        System.out.println(x); //"b"
        new Thread(new Runnable() {
            public void run() {
                String x = "c"; 
                System.out.println(x); //"c"
            }
        }).start();
        System.out.println(x); //"b"
    }

    public void method(){
        System.out.println(x); //"a"
    }
}

【讨论】:

  • 感谢您的回答,但我删除了final 并仅使用了String,但仍然不起作用。
  • 使用 final 声明一个常量。正如 AxelH 提到的,您仍然定义了一个新变量。也删除字符串。
  • @AhmedWas 我在答案中添加了一个有趣的东西,我注意到您已经在方法中定义了String x,因此您应该检查编辑。如果不清楚(不知道如何解释),请告诉我,我会尝试重新表述。
  • @AxelH,感谢男士的详细回答。现在一切正常:)
【解决方案2】:

该变量必须定义为类的实例变量,而不是方法中的局部变量。这样,所有按钮都将能够访问变量,而不仅仅是封装在方法中的那些。

编辑:

这里有一些示例代码可以准确地说明我的意思。 目前,您正在像这样定义变量 x:

final void initialize(){
    String x = "0"; //x is defined within the scope of this method only.
} 

这将变量 x 限制为仅存储在初始化方法中。但是,对于您的情况,您可能希望这样定义 x:

String x; //Instance variable which is available to the entire class
final void initialize(){
    x = "0"; //modifies the instance variable for the entire class 
}

【讨论】:

  • 你能用代码解释一下吗?谢谢!。
  • @AhmedWas 当然!看到代码后,这是一个非常简单的更改。
【解决方案3】:

您正在声明一个新变量 x,这就是问题所在。相反,您应该更改 x 并将其定义为成员变量(正如 IQV 在此答案下方的评论中所说)。

public void actionPerformed(ActionEvent e) {
    final String x = "1"; // this should be x = "";
    textField1.setText(x);
}

【讨论】:

  • 但我建议将x 定义为initialize() 之外的类变量。否则你可以在这个方法中使用xonly。
猜你喜欢
  • 2015-06-16
  • 2014-10-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-09
  • 1970-01-01
  • 1970-01-01
  • 2021-01-05
相关资源
最近更新 更多