Java 在return语句中创建匿名类

Java 在return语句中创建匿名类,java,generics,Java,Generics,我有以下静态方法: public static <E> Tree<E> leaf(E leaf) { return new Tree<E>() { @Override public <R> R accept(TreeVisitor<E, R> visitor) { return visitor.visit(leaf); //1 Ok in Java 8, fail in J

我有以下静态方法:

public static <E> Tree<E> leaf(E leaf) {
    return new Tree<E>() {
        @Override
        public <R> R accept(TreeVisitor<E, R> visitor) {
            return visitor.visit(leaf); //1 Ok in Java 8, fail in Java < 8
        }
    };
}
当我用Java8开发它的时候;它编译得很好,现在当我必须返回到Java 7时,//1行会导致编译错误:

无法引用在中定义的非最终局部变量叶 封闭范围


为什么Java 8允许引用非最终变量?

Java 8允许访问有效的最终变量,即非最终变量但可以标记为最终变量的局部变量,因为它们的值不会从匿名类和lambda表达式更改

通过使leaf成为最终版本,您可以克服旧Java版本中的编译问题:


Java 8允许访问有效的final变量,即非final但可以标记为final的局部变量,因为它们的值不会从匿名类和lambda表达式更改

通过使leaf成为最终版本,您可以克服旧Java版本中的编译问题:


是的,这实际上是您必须期望的,因为从Java 8开始:

局部类可以访问封闭块的局部变量和参数,这些变量和参数是final或实际上是final。一个变量或参数的值在初始化后永远不会改变,它实际上是最终的


实际上是最终的:一个变量或参数,其值在初始化后永远不会更改。

是的,这实际上是您所期望的,因为从Java 8开始:

局部类可以访问封闭块的局部变量和参数,这些变量和参数是final或实际上是final。一个变量或参数的值在初始化后永远不会改变,它实际上是最终的

有效的final:一个变量或参数,其值在初始化后不会改变

public static <E> Tree<E> leaf(final E leaf) {
    return new Tree<E>() {
        @Override
        public <R> R accept(TreeVisitor<E, R> visitor) {
            return visitor.visit(leaf); //1 Ok in Java 8, fail in Java < 8
        }
    };
}