본문 바로가기
Languages/Java

[Java] 람다식 (3) 클래스 멤버와 로컬 변수 사용

by 이래지 2021. 12. 30.
728x90

람다식의 실행 블록에는 클래스의 멤버(필드와 메소드) 및 로컬 변수를 사용할 수 있다. 클래스의 멤버는 제약 사항 없이 사용할 수 있지만, 로컬 변수는 제약 사항이 따른다. 


1. 클래스 멤버 사용


람다식 실행 블록에는 클래스의 멤버인 필드와 메소드를 제약 사항 없이 사용할 수 있다. 하지만 this 키워드를 사용할 때에는 주의가 필요하다. 

일반적으로 this는 익명 객체의 참조이지만, 람다식에서 this는 내부적으로 생성되는 익명 객체의 참조가 아니라 람다식을 실행한 객체의 참조이다. 

 

다음 예제는 람다식에서 바깥 객체와 중첩 객체의 참조를 얻어 필드값을 출력하는 방법이다. 

중접 객체 Inner에서 람다식을 실행했기 때문에 람다식 내부에서의 this는 중첩 객체 inner이다.

public interface MyFunctionalInterface {
	public void method();
}
// this 사용
public class UsingThis {
	public int outterField = 10;
    
    class Inner {
    	int innerField = 20;
        
        void method() {
        	MyFunctionalInterface fi = () -> {
            	System.out.println("outterField: " + outterField + "\n");
                System.out.println("outterField: " + UsingThis.this.outterfield + "\n");
				//바깥 객체의 참조를 얻기 위해서는 클래스명.this를 사용                
                System.out.println("innerField: " + innerField + "\n");
                System.out.println("innerField: " + this.innerField + "\n");
                //람다식 내부에서 this는 Inner객체를 참조
            };
            fi.method();
        }
    }
}

 

 

2. 로컬 변수 사용


람다식은 메소드 내부에서 주로 작성되기 때문에 로컬 익명 구현 객체를 생성 시킨다고 봐야한다.

람다식에서 바깥 클래스의 필드나 메소드는 제한 없이  사용할 수 있으나, 메소드의 매개 변수 또는 로컬 변수를 사용하면 이 두 변수는 final 특성을 가져야한다. (왜 final 특성을 가져야하는지 이유는 9장 인터페이스의 익명 객체의 로컬 변수 사용을 참고)

따라서 매개 변수 또는 로컬 변수를 람다식에서 읽는 것은 허용되지만, 람다식 내부 또는 외부에서 변경할 수 없다.

 

함수적 인터페이스

public interface MyFunctionalInterface {
	public void method();
}

final 특성을 가지는 로컬 변수

public class UsingLocalVariable {
	void method(int arg) { //arg 는 final 특성을 가짐 
    	int localVar = 40; //localVar 는 final 특성을 가짐 
        
        //arg = 31; //final 특성 때문에 변경 불가
        //localVar =41; //final 특성 때문에 변경 불가
        
        //람다식
        MyFunctionalInterface fi = () -> {
        	//로컬변수 읽기
            System.out.println("arg: " + arg);
            System.out.println("localVar: " + localVar + "\n") 
        };
        fi.method()
    }
}

실행 클래스

public class UsingLocalVariableExample {
	public static void main(String... args) {
    	UsingLocalVariable ulv = new UsingLocalVariable();
        ulv.method()
    }
}

댓글