java - How is it possible that when I pass a lambda expression as a parameter it can access other variables in this scope? -


public class arraysdemo {      public static void main(string[] args) {            int[] = {0, 2, 4, 6, 8};           int[] b = {10, 12, 14, 16, 18};           arrays.setall(a, -> b[i]+1);           system.out.println(arrays.tostring(a));     }   } 

outputs: [11, 13, 15, 17, 19]

the source of setall() function used follows:

public static void setall(int[] array, intunaryoperator generator) {         objects.requirenonnull(generator);         (int = 0; < array.length; i++)             array[i] = generator.applyasint(i); } 

intunaryoperator functional interface , part of source:

public interface intunaryoperator {     int applyasint(int operand);     // rest methods omitted } 

correct me if i'm wrong understanding of lambda expressions in java when pass lambda expression parameter setall() method, object of anonymous class implements intunaryoperator interface created , called generator. , lambda expression implementation of applyasint() method believe translate like:

int applyasint(int operand){     return b[operand]+1; } 

it makes sense me can access operand passed argument in array[i] = generator.applyasint(i); however, don't how can manipulate b - not passed parameter how possible can referenced? missing?

even without lambda expressions, e.g. using anonymous inner classes, can capture values of surrounding context, i.e.

int[] = {0, 2, 4, 6, 8}; int[] b = {10, 12, 14, 16, 18}; arrays.setall(a, new intunaryoperator() {     public int applyasint(int i) {         return b[i]+1;     } }); 

but there differences, though not relevant question. when using anonymous inner class, keywords this , super refer instance of inner class, whereas in lambda expressions, have same meaning in surrounding context. further, when inner class accesses private members of surrounding class, compiler insert helper method perform access, whereas lambda expressions can access members of theur containing class naturally.

to achieve this, code of lambda expression i -> b[i]+1 compiled synthetic method of your class having form:

private static int lambda$main$0(int[] b, int i) {     return b[i]+1; } 

and since it’s method within class, has access members.

so class generated @ runtime equivalent to

final class arraysdemo$lambda$1 implements intunaryoperator {     final int[] b;     arraysdemo$lambda$1(int[] b) {         this.b = b;     }     public int applyasint(int i) {         return arraysdemo.lambda$main$0(b, i);     } } 

the focus on word equivalent, not suggesting has (not speak of fact, ordinary java classes couldn’t access private method arraysdemo.lambda$main$0).


but these technical details, important key point lambda expressions can access effectively final local variables members of containing class , compiler , runtime environment ensure works. can consider them functions being evaluated in context defined.


Comments

Popular posts from this blog

amazon web services - S3 Pre-signed POST validate file type? -

c# - Check Keyboard Input Winforms -