闭包原理
在Java的匿名内部类和lambda使用外部变量时,必须是effectly final。实际上Java在编译时通过隐式修改构造方法来捕捉外部变量。由于Java中方法参数是值传递,为了保证一致性,防止外部变量修改,因此有了这个要求。
规避的这个要求,通常使用的方法有两种。一是使用包装类,基本类型可以使用对应的Atomic类型,引用类型则使用AtomicReference。二是通过方法引用,只能用于lambda,创建一个签名一样的方法,代替原有的函数。
非静态的内部类可以直接访问外部类的实例变量。在非静态内部类创建时,将外部类的引用传递给它,因为内部类实例需要通过外部类实例创建,所以这没有问题。
个人想法
箭头表达式被运行后,返回的是一个实现接口的实例。它能访问到定义类或实例中的变量。但是,如果在方法中创建的,那么它还可以访问方法的参数。这和非静态内部类的情况有所不同。如果lambda直接访问外部变量,还可能带来其他问题。
命名混乱
和方法区分,纯粹的函数没有绑定上下文,只有局部变量
线程安全
在多线程,比如ParallelStream中使用可能出现问题
复用
箭头表达式被多次运行,可以复用同一实例,无需重新编译。而当捕获外部变量,则不一定能复用。