当前位置: 首页 > 知识库问答 >
问题:

有效的终局/最终限制不是没用的吗?[副本]

百里芷阳
2023-03-14
public class Main {
    @FunctionalInterface
    interface Test {
        void method(int t);
    }

    static void test(Test t) {
        t.method(3);
    }

    public static void main(String... args) {
        int a = 3;
        test((i)-> {
            System.out.println(a + i);
        });
    }
}

编译器所做的是复制该变量,就像它是通过构造函数传递的一样。我上了这三节课:

1:

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

import Main.1;
import Main.Test;

public class Main {
    public Main() {
    }

    static void test(Test var0) {
        var0.method(3);
    }

    public static void main(String... var0) {
        byte var1 = 3;
        test(new 1(var1));
    }
}

2:

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

import Main.Test;

final class Main$1 implements Test {
    Main$1(int var1) {
        this.val$a = var1;
    }

    public void method(int var1) {
        System.out.println(this.val$a + var1);
    }
}
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

@FunctionalInterface
interface Main$Test {
    void method(int var1);
}

为什么实现者不能直接复制变量,不管它是否被修改,所以我们可以这样做:

public class Main {
    @FunctionalInterface
    interface Test {
        void method(int t);
    }

    static void test(Test t) {
        t.method(3);
    }

    public static void main(String... args) {
        int a = 3;
        test((i)-> {
            a += 1; // allow modification, a is copied anyway, why not?
            System.out.println(a + i);
        });
    }
}

共有1个答案

柳飞飙
2023-03-14

这没有技术上的原因。只是如果您允许在lambda中使用非final字段,那么您可以编写看起来很好,但实际上不起作用的代码。

例如:

void printSum(Collection<Integer> numbers) {
  int sum = 0;
  numbers.forEach(i -> sum += i);
  System.out.println(sum);
}

目前编译器不允许您这样做,因为您不能访问lambda中的非finalsum。正如您所指出的,变量无论如何都会被复制到lambda中,所以它可以允许这样做。

 类似资料:
  • 我在Java8中使用lambdas,我遇到了警告,从lambda表达式引用的。我知道当我在匿名类中使用变量时,它们在外部类中必须是final的,但final和有效的final有什么区别?

  • 到目前为止,我认为有效的final和final或多或少是等价的,如果在实际行为中不完全相同,JLS会将它们视为相似的。然后我发现了这个人为的场景: 显然,JLS在这两者之间产生了重要的区别,我不知道为什么。 我阅读其他线程,如 最终和有效最终之间的差异 有效的最终变量vs最终变量 变量“有效最终”是什么意思 但他们并没有详细说明。毕竟,在更广泛的层面上,它们似乎几乎相当。但深入研究,他们显然有所不

  • 我正在使用RxVertx,它是一种RxJava和Java8,我有一个编译错误。 这是我的代码: 编译错误是:“在封闭范围内定义的局部变量游戏必须是最终的或有效的最终的” 我无法将“game”定义为final,因为我在函数末尾执行分配\set并返回它。 如何编译此代码? 谢了。

  • 在Java8中,Java设计者提出了一个有效的final变量的概念,即一个如果被“final”追加就不会给编译器带来错误的变量。我的问题是,这个新提出的“有效最终”概念比经典的“最终”提供了什么?作为一名Java开发人员,我实际上得到了什么好处?

  • 本文向大家介绍Java中的StringBuffer是最终版本吗?,包括了Java中的StringBuffer是最终版本吗?的使用技巧和注意事项,需要的朋友参考一下 是的,StringBuffer类是最终的Java。我们不能覆盖此类。