πŸ“– Java λžŒλ‹€μ˜ λ³€μˆ˜ λ²”μœ„


λžŒλ‹€μ˜ λ³€μˆ˜ λ²”μœ„

image

λ¬Όλ‘  μœ„μ˜ μ½”λ“œλŠ” λ―Έμ…˜μ„ μœ„ν•΄ 일단 κ΅¬ν˜„λ§Œμ„ λͺ©μ μœΌλ‘œ λ§Žμ€ λ¦¬νŒ©ν† λ§μ΄ ν•„μš”ν•˜λ‹ˆ μ°Έκ³  πŸ₯²
λ―Έμ…˜μ„ μ§„ν–‰ν•˜λ‹€κ°€ for λ¬Έ 내에 stream을 μ“°κ²Œ λ˜μ—ˆλŠ”λ°, i의 값을 λžŒλ‹€μ‹ λ‚΄μ—μ„œ μ‚¬μš©ν•˜λ €λ‹ˆ 컴파일 μ—λŸ¬κ°€ 났닀.
β€œVariable used in lambda expression should be final or effectively final” 즉 λžŒλ‹€μ‹μ—μ„œ μ‚¬μš©λ˜λŠ” λ³€μˆ˜λŠ” finalμ΄κ±°λ‚˜ effectively final이어야 ν•œλ‹€.

effectively final은 무엇이며, λžŒλ‹€μ˜ λ³€μˆ˜ λ²”μœ„λ₯Ό μ •ν™•νžˆ 짚고 λ„˜μ–΄κ°€μž.

λžŒλ‹€μ˜ λ³€μˆ˜ λ²”μœ„

λ‹€μŒκ³Ό 같은 Lambda ν΄λž˜μŠ€κ°€ 있고, 각각의 λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•΄ 클래슀 ν•„λ“œμΈ iκ°€ μ–΄λ–»κ²Œ λ°”λ€ŒλŠ”μ§€ μ‚΄νŽ΄λ³Έλ‹€ πŸ”Ž

public class Lambda {
    private int i = 1;

    public Integer example1() {
        Supplier<Integer> function = () -> i * 5;
        return function.get();
    }

    public Integer example2(int i) {
        Supplier<Integer> function = () -> i * 10;
        return function.get();
    }

    public Integer example3() {
        int i = 1;
        Supplier<Integer> function = () -> i * 15;
        return function.get();
    }
}

image

이에 λŒ€ν•œ 좜λ ₯ κ²°κ³ΌλŠ” λ‹€μŒκ³Ό κ°™λ‹€.

image

μœ„ μ˜ˆμ œμ—μ„œ λžŒλ‹€μ‹μ—μ„œλŠ” μžμ‹ μ„ 감싼 λ©”μ„œλ“œλ‚˜ ν΄λž˜μŠ€μ— μ†ν•œ λ³€μˆ˜μ— 접근을 ν•  수 μžˆλ‹€.
μ˜ˆμ œλŠ” λžŒλ‹€μ— νŒŒλΌλ―Έν„°λ‘œ λ„˜κ²¨μ§„ λ³€μˆ˜κ°€ μ•„λ‹Œ μ™ΈλΆ€μ—μ„œ μ •μ˜λœ λ³€μˆ˜λ₯Ό μ‚¬μš©ν•˜κ³  μžˆλŠ”λ° μ΄λŸ¬ν•œ λ³€μˆ˜λ₯Ό 자유 λ³€μˆ˜λΌκ³  λΆ€λ₯Έλ‹€.

κ·Έλ ‡λ‹€λ©΄ λ‹€μ‹œ 맨 처음 였λ₯˜λ₯Ό κ°€μ Έμ™€μ„œ … image

이 λΆ€λΆ„μ—μ„œ μ™œ 자유 λ³€μˆ˜μΈ iλ₯Ό finalμ΄λ‚˜ effectvely final둜 μ„ μ–Έν•˜λΌλŠ” κ²ƒμΌκΉŒ ?

λ¨Όμ € 지역 λ³€μˆ˜λŠ” JVMμ—μ„œ μŠ€νƒ μ˜μ—­μ— μ €μž₯이 λœλ‹€.
그리고 μ‹€μ œ λ©”λͺ¨λ¦¬μ™€ λ‹€λ₯΄κ²Œ JVMμ—μ„œ 이 μŠ€νƒ μ˜μ—­μ€ μŠ€λ ˆλ“œ λ§ˆλ‹€ λ³„λ„μ˜ μŠ€νƒμ΄ μƒμ„±λœλ‹€.
λ”°λΌμ„œ 지역 λ³€μˆ˜λŠ” ν•œ μŠ€λ ˆλ“œ μ•ˆμ—μ„œλ§Œ μ‚¬μš©μ΄ 되며, μŠ€λ ˆλ“œλΌλ¦¬ κ³΅μœ ν•˜μ§€ λͺ»ν•œλ‹€.

참고둜 지역 λ³€μˆ˜μ™€ λ‹€λ₯΄κ²Œ μΈμŠ€ν„΄μŠ€ λ³€μˆ˜λŠ” νž™ μ˜μ—­μ— μƒμ„±λ˜μ–΄ μ„œλ‘œ λ‹€λ₯Έ μŠ€λ ˆλ“œλΌλ¦¬λ„ κ³΅μœ ν•  수 μžˆλŠ” 곡유 λ³€μˆ˜μ΄λ‹€.

λžŒλ‹€λŠ” 각각 λ³„λ„μ˜ μŠ€λ ˆλ“œμ—μ„œ 싀행이 κ°€λŠ₯ν•˜λ‹€.
λžŒλ‹€κ°€ 지역 λ³€μˆ˜μ— μ ‘κ·Όν•˜λ € ν•  λ•Œμ—λŠ” 지역 λ³€μˆ˜κ°€ μ‘΄μž¬ν•˜λŠ” μŠ€νƒ μ˜μ—­μ— 직접 μ ‘κ·Όν•˜μ§€ μ•Šκ³  이 λ³€μˆ˜μ˜ 볡사본을 λ§Œλ“€μ–΄ λ™μž‘ν•œλ‹€. 이λ₯Ό λžŒλ‹€ 캑처링이라고 ν•œλ‹€. λ•Œλ¬Έμ— 이 볡사본을 가지고 λ™μž‘ν•  μ˜ˆμ •μΈλ°, λ°˜ν™˜λœ λžŒλ‹€μ‹μ€ μ—¬λŸ¬ μŠ€λ ˆλ“œμ—μ„œ λ™μž‘ν•  수 있기 λ•Œλ¬Έμ— 동기화 λ¬Έμ œκ°€ 일어날 수 μžˆλ‹€.
λ•Œλ¬Έμ— 이 볡사본 값이 λ°”λ€Œμ–΄ 버리면 μ˜λ„ν•˜μ§€ μ•Šμ€ κ²°κ³Όκ°€ 생길 수 μžˆμœΌλ―€λ‘œ 컴파일 λ‹¨κ³„μ—μ„œ
final λ˜λŠ” effectively final둜 μ„ μ–Έν•΄ λ³€μˆ˜λ₯Ό μ‹ λ’°ν•  수 있게 λ§Œλ“œλŠ” 것이닀.
이λ₯Ό λžŒλ‹€ 캑처링이라고 ν•œλ‹€.

μœ„ λ¬Έμ œμ—μ„œ 컴파일 μ—λŸ¬κ°€ λœ¨λŠ” 것은 iκ°€ μŠ€μ½”ν”„ 밖에 μžˆμ–΄ 값이 λ³€ν•  수 μžˆμ–΄ μ‹ λ’°ν•  수 μ—†λ‹€.
λ•Œλ¬Έμ— μΈν…”λ¦¬μ œμ΄κ°€ κΆŒν•΄μ£ΌλŠ” 방법을 μ“°λ©΄ iλ₯Ό μŠ€μ½”ν”„ μ•ˆ λ³€μˆ˜μ— μƒˆλ‘œ ν• λ‹Ήν•΄μ„œ μ‚¬μš©ν•˜κ²Œ λœλ‹€.
image

μ—¬κΈ°μ„œ iλŠ” final 둜 μ„ μ–Έλ˜μ§€λŠ” μ•Šμ•˜μ§€λ§Œ, μžλ°” 8μ—μ„œ μΆ”κ°€λœ effectively final둜 μ„ μ–Έλœ 것이닀.
effectively final은 final둜 μ„ μ–Έλ˜μ§€ μ•Šμ•„λ„ μ»΄νŒŒμΌλŸ¬κ°€ ν•΄λ‹Ή λ³€μˆ˜κ°€ λ³€κ²½λ˜μ§€ μ•Šμ•˜λ‹€κ³  νŒλ‹¨ν•  수 μžˆλ‹€.

image

λ§Œμ•½ effectively final인 i의 값을 λ°”κΎΈλ € ν•œλ‹€λ©΄ μ΄λ ‡κ²Œ 컴파일 였λ₯˜κ°€ λ°œμƒν•œλ‹€.

νŒŒλ„ νŒŒλ„ λμ—†λŠ” λžŒλ‹€μ˜ 세계 πŸ€Έβ€β™€οΈ

참고 자료