Java 8 lambda范围问题 intx=1; 消费者f=(i)->{ int x=1;//无效 };

Java 8 lambda范围问题 intx=1; 消费者f=(i)->{ int x=1;//无效 };,java,closures,java-8,Java,Closures,Java 8,vs 消费者f=(i)->{ int x=1; }; int x=1;//有效的 想象一下一个方法中的这两个块。为什么第二个块有效?在第一个块中,您是“原始x变量”。通过创建新的x,您将无法再访问第一个x 第二个块没有问题,因为第二个x是在第一个x不再存在(超出范围)的时刻创建的 基本上:在第一种情况下,您试图同时拥有两个名为x的变量。在第二种情况下,您将在两个变量之后创建两个x变量:它们的生存期不会重叠。这与普通Java作用域非常相似: Consumer<Object>

vs

消费者f=(i)->{
int x=1;
};
int x=1;//有效的

想象一下一个方法中的这两个块。为什么第二个块有效?

在第一个块中,您是“原始
x
变量”。通过创建新的
x
,您将无法再访问第一个
x

第二个块没有问题,因为第二个
x
是在第一个
x
不再存在(超出范围)的时刻创建的


基本上:在第一种情况下,您试图同时拥有两个名为
x
的变量。在第二种情况下,您将在两个变量之后创建两个
x
变量:它们的生存期不会重叠。

这与普通Java作用域非常相似:

    Consumer<Object> f = (i) -> {
        int x = 1;
    };
    int x = 1; // valid
vs


那么为什么“范围”不是对称的呢。若lambda是如此透明,那个么它应该是对称的,但作用域根本不是对称的。甚至对于像
for
循环或
if
statements.lol这样的构造也不一样,所以lambda(好像块等)不创建命名范围,而是创建生存期范围?为什么?当然,允许在内部作用域中重新定义(如“隐藏”)变量是一种完全合法的设计。再说一遍,这只是语言设计。但它带来了一定程度的混乱(根据作用域的不同处理同名变量和不同的值),没有实际的好处(仅仅使用不同的名称就足够容易了)。+1。这与兰博达斯无关;e、 匿名类将施加相同的约束。我将要写完全相同的东西!
    Consumer<Object> f = (i) -> {
        int x = 1;
    };
    int x = 1; // valid
int i;
{
    int i;      // invalid
}          
{
    int i;      // valid
}

int i;