简体   繁体   English

从内部 class 访问的变量需要声明为 final

[英]Variable accessed from within inner class needs to be declared final

Hello I am trying to do pretty much the exact same thing as the person who asked this question: Variable is accessed from within inner class needs to be declared final您好,我正在尝试做与提出这个问题的人几乎完全相同的事情: Variable is access from inside class need to be declared final

So I'm going to continue to use their code as a reference in this question:所以我将继续使用他们的代码作为这个问题的参考:

 File directory = new File(prefs.getString("path",null));
 File[] files = directory.listFiles();
        for (File file :files){
            if(file.isDirectory()) {
                buttons.add(new Button(this));
                Button button = buttons.get(buttons.size() - 1);
                String fileName = file.getName();

                button.setText(fileName);
                button.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        Intent intent = new Intent(currentActivity, EOChoiceActivity.class);
                        intent.putExtra("fileExtension",fileName);
                        startActivity(intent);
                    }
                });
                layout.addView(button);
            }
        }

I'm asking the same question as the original author also: why is it that only the last fileName selected is sent for any button?我也在问与原作者相同的问题:为什么只为任何按钮发送选择的最后一个文件名? I understand that this has to do with the rules of how an inner class accesses local variables, as cited in JLS 8.1.3, but I still just can't understand the reasoning.我知道这与 JLS 8.1.3 中引用的内部 class 访问局部变量的规则有关,但我仍然无法理解其中的原因。

The only thing I can think of that makes sense of this is that the inner class is using a reference of fileName, and so when the fileName value changes on each iteration, and eventually is solidified in it's value on the last iteration, the "final" reference would be to the value of the last element in the files array and this reference would be present for each button.我能想到的唯一有意义的是,内部 class 正在使用文件名的引用,因此当文件名值在每次迭代中发生变化,并最终在最后一次迭代中固化为它的值时,“最终" 引用将指向 files 数组中最后一个元素的值,并且该引用将出现在每个按钮上。

Yeah I'm just really confused here... I can't understand why the different values for fileName wouldn't apply to each button, but instead only the last fileName value is applied to each button.是的,我在这里真的很困惑......我不明白为什么 fileName 的不同值不适用于每个按钮,而是只有最后一个 fileName 值应用于每个按钮。

I do not understand the question, neither the original .我不明白这个问题,也不是原来的 . I do not work with android, but with Java.我不使用 android,但使用 Java。 So I did the following test:所以我做了以下测试:

JPanel buttons = new JPanel();
File directory = new File(".");
File[] files = directory.listFiles();
for (File file :files) {
    if (file.isDirectory()) {
        JButton button = new JButton();
        buttons.add(button);
        final String fileName = file.getName();
        button.setText(fileName);
        button.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent ev) {
                System.out.println(fileName);
            }
        });
    }
}
JOptionPane.showMessageDialog(null, buttons);

and all is working as expected that is, when pressing any button, I get its text sent to the standard output.一切都按预期工作,即当按下任何按钮时,我会将其文本发送到标准 output。

Regarding the original question, there should be no difference if the variable is declared final or not.关于原始问题,变量是否声明为final应该没有区别。
Maybe the author got confused since compiler of older versions (before Java 8) would generate an error if such variable was not declared final ;也许作者感到困惑,因为如果未将此类变量声明为final ,则旧版本(Java 8 之前)的编译器会产生错误; with Java 8 or newer, the variable must only be effectively final (document in JLS 8.1.3).对于 Java 8 或更高版本,该变量只能是有效的final变量(JLS 8.1.3 中的文档)。

Sure, if fileName was declared as a class field (not a variable), then the last value set would be the one sent for all buttons (the value of fileName when the button is pressed).当然,如果fileName被声明为 class 字段(不是变量),那么最后设置的值将是为所有按钮发送的值(按下按钮时fileName的值)。

If fileName is a variable, then it stops existing when the execution of the block it is in is terminated - so its value must be stored in the created instance(s) of the inner class - it would be confusing if the variable was assigned a new value after the creation of that instance - must the saved value be actualized?如果fileName是一个变量,那么当它所在的块的执行终止时它就会停止存在- 因此它的值必须存储在内部 class 的创建实例中 - 如果变量被分配了一个创建该实例后的新值 - 必须实现保存的值吗? Or should the old value be used?还是应该使用旧值? I believe that is one of the reason for the requirement of being final.我相信这是最终要求的原因之一。 See Jons explanation here - surely better than mine.请参阅 Jons的解释- 肯定比我的要好。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 “从内部类访问变量需要声明为final”错误 - "variable is accessed from within inner class needs to be declared final" error 从内部类访问变量“ ”,需要声明为 final - Variable ' ' is accessed from within inner class, needs to be declared final 变量(dialogView)是从内部类中访问的,需要声明为final - Variable (dialogView) is accessed from within inner class, needs to be declared final 从内部类访问变量“i”,需要声明为 final - Variable 'i' is accessed from within inner class, needs to be declared final 变量'btnsave'是从内部类中访问的,需要声明为final - Variable 'btnsave' is accessed from within inner class, needs to be declared final 在内部类中访问变量。 需要宣布为最终 - Variable is accessed within inner class. Needs to be declared final 在内部类中访问变量“名称”。 需要宣布为最终 - Variable “name” is accessed within inner class. Needs to be declared final 需要在OnTouchListener中用MediaPlayer声明内部类中访问的变量的最终声明 - Variable Is Accessed Within Inner Class Needs to be Declared Final with MediaPlayer In a OnTouchListener 在内部类中访问如何解析变量,并且需要将其声明为final - How to resolve variable is accessed within inner class and needs to be declared final 从内部类访问,需要声明为final - is accessed from within inner class, needs to be declared final
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM