Java 在对象的情况下使用final关键字

Java 在对象的情况下使用final关键字,java,java-8,Java,Java 8,我知道如何使用final关键字。假设如果将一个类设为final,那么它就不能被继承;如果一个方法是final,那么它就不能被重写;如果一个变量设为final,那么它的值就不能被更改。但在这种情况下,我有点困惑 final TextField urlTextField = new TextField(); 我认为,如果urlTextField是最终的,那么你就不能再做一次 urlTextField=new textField()。但在下面的示例中,为什么它是最终的 在Java 7中,当

我知道如何使用final关键字。假设如果将一个类设为final,那么它就不能被继承;如果一个方法是final,那么它就不能被重写;如果一个变量设为final,那么它的值就不能被更改。但在这种情况下,我有点困惑

    final TextField urlTextField = new TextField();
我认为,如果urlTextField是最终的,那么你就不能再做一次

urlTextField=new textField()。但在下面的示例中,为什么它是最终的


在Java 7中,当您在一个匿名类中,并且您试图使用/接近包装类的一个变量时,该变量应该声明为
final
,否则编译器会抱怨。同样的事情也适用于Lambda表达式(Java8支持)。尝试从声明中删除
final
,您将在第4行看到编译器错误:

    urlTextField.setOnAction( aEvent ->  {
        pageLoadedProperty.set(false);
        printButtonClickedProperty.set(false);
        webEngine.load(urlTextField.getText()); // <-- compile error 
    });  

在Java7之前,您需要声明一个局部变量final,以便从内部类访问它

从Java8开始,这不再是必需的:(即,未更改)。该更改是为了与lambda语法保持一致


因此,从技术上讲,如果使用Java FX 8,这里不需要final关键字。

通过使用
final
one声明此变量不能更改(通过重新赋值)。问题是什么?在本例中使用
final
是为了允许嵌套类/闭包访问对象(即
start
方法中的事件处理程序)@MadProgrammer not class-closure(可能被转换为内部匿名类);)@alfasin不是FX开发者-对不起,淘气的我:P@MadProgrammer它与FX无关-我认为Java 8开始支持闭包,所以我们很快就会知道它到底是什么:)在给定的代码中,什么是内部类,我也没有创建任何匿名类{…正在创建一个闭包。我的答案的最后一段提到了。如果我记得正确(而且他们没有更改它),那么当变量是“有效的最终变量”时,访问闭包中的变量也会起作用(即,您不必编写
最终的
,但您必须遵循它的大部分规则)@JoachimSauer不是根据我答案中的最后一个链接;)@assylias是的,它必须是最终的或有效的最终的,这意味着它不是最终的,但我们仍然不能在lambda的体内更改它。你在这里写的所有东西-都已经在上面的答案+评论中提到过了。@assylias谢谢你的回答,好的观点to了解so+1。我有点困惑。你说“在Java 7之前,你需要声明一个局部变量final才能从内部类访问它”。在我的代码中,这是内部类。@Java初学者,我有一个Déjávu:)@alfasin你的答案是“尝试从声明中删除final,您将看到在第4行出现编译器错误”,这与Java 8(用于问题的标记)是错误的,因此我认为发布更准确的答案会很有用。@assylias您是对的-即使支持闭包,lambda表达式(
->
)Java 7中不支持。要更新我的答案吗
    urlTextField.setOnAction( aEvent ->  {
        pageLoadedProperty.set(false);
        printButtonClickedProperty.set(false);
        webEngine.load(urlTextField.getText()); // <-- compile error 
    });  
        // The following statement causes the compiler to generate
        // the error "local variables referenced from a lambda expression
        // must be final or effectively final" in statement A:
        //
        // x = 99;

        Block<Integer> myBlock = (y) -> 
        {
            System.out.println("x = " + x); // Statement A
            System.out.println("y = " + y);
            System.out.println("this.x = " + this.x);
            System.out.println("LambdaScopeTest.this.x = " +
                LambdaScopeTest.this.x);
        };