引用非final变量:为什么这段代码会编译? [英] Referencing non-final variable: why does this code compile?

查看:250
本文介绍了引用非final变量:为什么这段代码会编译?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

首先,如果这是一个重复的问题,我道歉。我找到了许多类似的,但没有一个直接解决我的问题。

First off, I apologise if this is a duplicate question. I found many similar ones, but none that directly address my question.

为了准备即将到来的考试,我正在做一篇过去的论文。它有一个提供代码段的问题。我们必须声明它是否编译,如果不编译,则写入发生第一个编译器错误的行并解释它。这是片段:

In preparation for an upcoming exam, I am doing a past paper. It has a question that gives a code snippet. We have to state if it compiles, and if not, write the line at which the first compiler error occurs and explain it. This is the snippet:

public static void main(String[] args) {
    JFrame f = new JFrame("hi");
    JTextField jtf = new JTextField(50);

    jtf.addMouseMotionListener(new MouseMotionAdapter() {
        public void mouseMoved(MouseEvent evt) {
            jtf.setText(evt.getLocationOnScreen().toString());
        }
    });

    f.add(jtf);
    f.setVisible(true);
}

我原以为它不能编译成 jtf 不是 final 。我通过在Eclipse中输入上面的代码来测试我的理论,它标记了预期的错误,但编译并运行得很好。只有在鼠标悬停在 JTextField 之后我才得到预期的错误:

I was expecting it not to compile as jtf is not final. I tested my theory by entering the code above in Eclipse, which flagged the expected error, but compiled and ran just fine. It was only after mousing over the JTextField that I got the expected error:


java.lang.Error:未解决的编译问题:
不能引用封闭范围中定义的非最终局部变量jtf

java.lang.Error: Unresolved compilation problem: Cannot refer to the non-final local variable jtf defined in an enclosing scope



<我做了一些搜索,发现Eclipse使用自己的Java编译器版本。所以我在Eclipse之外重新创建了文件,并通过命令行编译/运行它。编译时没有错误或警告,当鼠标悬停在文本字段上时,显示所需的 java.awt.Point [x = ...,y = ...]

我对匿名内部类的理解是他们可以访问:

My understanding of anonymous inner classes is that they can access:


  • 封闭类的字段

  • 封闭类的方法

  • 封闭范围的局部变量,前提是它们是 final

  • Fields of the enclosing class
  • Methods of the enclosing class
  • Local variables of the enclosing scope, provided they are final

那么我错过了什么?据我所知,此代码不应该

So what am I missing? According to what I know, this code should not work.

推荐答案

我猜你正在编译Java 8.这里你的 jtf 变量实际上是最终的,所以它编译得很好。如果变量初始化后它的值永远不会改变,那么变量实际上是最终的。

I guess you are compiling with Java 8. Here your jtf variable is effectively final, so it compiles fine. A variable is effectively final if its value is never changed after you initialized it.

另请参阅本地类


但是,从Java SE 8开始,本地类可以访问本地
变量和参数封闭的块是最终的,或
有效的最终。初始化后值为
的变量或参数实际上是最终的。

However, starting in Java SE 8, a local class can access local variables and parameters of the enclosing block that are final or effectively final. A variable or parameter whose value is never changed after it is initialized is effectively final.

访问本地变量包含范围,以及声明和访问匿名类的成员


与本地类一样,匿名类可以捕获变量;他们有
对封闭范围的局部变量的相同访问权限:

Like local classes, anonymous classes can capture variables; they have the same access to local variables of the enclosing scope:


  • 匿名类可以访问成员它的封闭类。

  • An anonymous class has access to the members of its enclosing class.

匿名类无法访问其封闭的
范围内的本地变量,这些变量未被声明为最终或有效最终。

An anonymous class cannot access local variables in its enclosing scope that are not declared as final or effectively final.

[...]

如果您尝试过:

javac -source 1.7 MyFile.java

你会得到预期的错误。

.java:13: error: local variable jtf is accessed from within inner class; needs to be declared final
                jtf.setText(evt.getLocationOnScreen().toString());
                ^
1 error

因此,考试问题的答案是:它只有在使用Java 8 +时编译。

So the answer of the exam question is: it compiles only if you're using Java 8+.

这篇关于引用非final变量:为什么这段代码会编译?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆