Because a lambda cannot capture a reassignable local variable, code that needs shared mutable state captures a one-element array or an AtomicInteger instead, whose reference is effectively final even though its contents change.
int[] counter = {0};
Runnable increment = () -> counter[0]++;
increment.run();
increment.run();
increment.run();
System.out.println("Counter via array: " + counter[0]);
AtomicInteger atomic = new AtomicInteger(0);
Runnable incrementAtomic = atomic::incrementAndGet;
incrementAtomic.run();
incrementAtomic.run();
System.out.println("Counter via AtomicInteger: " + atomic.get());
Counter via array: 3
Counter via AtomicInteger: 2
Run this yourself in the Online Java Compiler, spin up a live REST API in the API Sandbox, or practise with Java interview questions.
Published 2026-09-27