배운 것 기록/java

람다식 표현과 this

키죽 2022. 7. 2. 22:26
package Lambda;

// 1. 파라미터와 리턴타입이 없는 경우 (파라미터: X, 리턴타입: X)
@FunctionalInterface
interface MyFunc1 {
	// 함수형 인터페이스 어노테이션(@FunctionalInterface) 선언 시 에러 발생!
	// => 함수형 인터페이스는 반드시 하나의 추상메서드(abstract method)를 가져야함
	public void methodA();
//	public void methodB();
}

// 2. 파라미터가 있는 람다식 (파라미터: O, 리턴타입: X)
@FunctionalInterface
interface MyFunc2 {
	void methodB(String msg);
}

// 3. 리턴타입이 있는 람다식 (파라미터: O, 리턴타입: O)
@FunctionalInterface
interface MyFunc3 {
	String methodC(String msg);
}


public class Ex2 {

	// 1. 파라미터와 리턴타입이 없는 경우 (파라미터: X, 리턴타입: X)
	public static void useFIMethodA(MyFunc1 fi) {
		fi.methodA();
	}
	
	// 2. 파라미터가 있는 람다식 (파라미터: O, 리턴타입: X)
	public static void useFIMethodB(MyFunc2 fi) {
		fi.methodB("홍길동");
	}
	
	// 3. 리턴타입이 있는 람다식 (파라미터: O, 리턴타입: O)
	public static String useFIMethodC(MyFunc3 fi) {
		return fi.methodC("홍길동");
	}
	
	public static void main(String[] args) {
		
		useFIMethodA(new MyFunc1() {
			
			@Override
			public void methodA() {
				System.out.println("익명 내부클래스 형태");
			}
		});
		System.out.println("-------------------------------");
		
// 1. 파라미터와 리턴타입이 없는 경우 (파라미터: X, 리턴타입: X)
		System.out.println("(파라미터: X, 리턴타입: X)");
		
		// 표현방식1
		useFIMethodA(() -> {
			System.out.println("람다식2");
		});
		
		// 표현방식2
		useFIMethodA(() -> System.out.println("람다식1"));
		
		System.out.println("------------------------");
        
// 2. 파라미터가 있는 람다식 (파라미터: O, 리턴타입: X)
		System.out.println("(파라미터: O, 리턴타입: X)");
		
		// 표현방식1
		useFIMethodB((String msg) -> {
			System.out.println("람다식1 : " + msg);
		});
		
		// 표현방식2
		// 파라미터 갯수:1 , 실행문:1 --> 소괄호(), 중괄호{} 생략 가능!
		useFIMethodB(msg -> System.out.println("람다식2 : " + msg));
		
		System.out.println("------------------------");
        
// 3. 리턴타입이 있는 람다식 (파라미터: O, 리턴타입: O)
		System.out.println("(파라미터: O, 리턴타입: O)");
		
		// 표현방식1
		String result = useFIMethodC((String msg) -> { 
			return "람다식1 : " + msg;
		});
		System.out.println(result);
		
		// 표현방식2
		System.out.println(useFIMethodC(msg -> "람다식2 : " + msg));
		
	}
}

출력 결과

 

람다의 실행블록에서 변수 참조 (this)

람다식은 컴파일러에 의해 익명의 내부클래스로 처리되기 때문에 변수에 대한 참조 규칙이 동일하다.
- 외부클래스의 멤버를 자유롭게 사용할 수 있다.
- 자바8부터는 일반 로컬 변수도 사용할 수 있는데 final 키워드가 적용된 것처럼 새로운 값을 할당할 수는 없다!

하지만 this를 사용하는 방법이 약간 다르다.
- 람다식에서 this는 타켓인터페이스가 아닌 외부클래스를 나타낸다.
- 따라서, 람다식 내에서 this와 외부클래스.this는 동일한 객체를 나타낸다.