在return语句中创建一个匿名类

时间:2015-07-13 07:09:22

标签: 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 Java < 8
        }
    };
}

我在Java 8中开发它;它编译得很好,现在当我不得不回到Java 7时,行//1会导致编译错误:

  

不能引用一个中定义的非最终局部变量leaf   封闭范围

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

2 个答案:

答案 0 :(得分:3)

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

您可以通过leaf final来克服旧Java版本中的编译问题:

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
        }
    };
}

答案 1 :(得分:3)

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

  

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

Documentation

有效最终:一个变量或参数,其值在初始化后永远不会改变。