为什么书上说这里需要final关键字?

4

这段代码来自于《Java编程思想》一书。我不知道为什么必须在这里加上final关键字。我删除了final并且程序仍然可以编译。然而,书中说我必须添加它。

// initialization. A briefer version of Parcel5.java.
public class Parcel9 {
    // Argument must be final to use inside
    // anonymous inner class:
    public Destination destination(final String dest) {
        return new Destination() {
            private String label = dest;
            public String readLabel() { return label; }
        };
    }
    public static void main(String[] args) {
        Parcel9 p = new Parcel9();
        Destination d = p.destination("Tasmania");
    }
} ///:~

理想情况下,这本书应该像 return new Destination(dest) 这样教授,并使用不同的例子。 - OneCricketeer
匿名类的最终要求是让编译器在幕后完成使其工作的神奇操作。 - Thorbjørn Ravn Andersen
1个回答

11

很有可能这本书(或章节/部分)是在Java 8时代之前编写的。

Java对匿名类施加了限制,除非它是final,否则不能访问局部变量。

在Java 8中,这个限制也适用于lambda表达式。但是,除此之外,Java 8还添加了“有效地final”的概念,通过检测该变量没有在本地重新赋值来使编译器更加智能化,从而使这种情况下使用final关键字是可选的。

因此,如果您在Java 7或更早版本上编译该代码,您将得到编译器错误,而这本书正在教导读者避免这种情况。


Java 8 中是否取消了匿名类的最终要求? - Thorbjørn Ravn Andersen
@ThorbjørnRavnAndersen 提升了吗?没有。唯一的新东西是有效终态的概念。变量仍然必须是终态,但开发人员不再需要显式地使用 final 关键字(即,如果变量被重新分配,在匿名类中使用编译器将会抱怨)。 - ernest_k
那么就不需要“Java 7或更早版本”了。 - Thorbjørn Ravn Andersen
@ThorbjørnRavnAndersen 我怀疑您在这里忽略了一个微妙的点。当 OP 的机器上移除 final 关键字时,编译器不会引发错误,因为他们的编译器更新。然而,该书是针对旧版本的 Java 编写的(其中需要显式使用 final 关键字)。因此,如果 OP 想要看到错误,他们应该尝试在 JDK 7 或更早版本上构建代码(不使用 final)。 - ernest_k
1
我错过了微妙的点。我在问是否匿名类现在只需要_effectively_ final,看起来是这样的。今天学到了新东西(虽然真的很好 - 让代码更清洁) - Thorbjørn Ravn Andersen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接