프로그래밍Java 개발자

자바에서 람다 표현식과 함수형 인터페이스가 어떻게 작동하는지 설명하십시오. 잘못 사용했을 때 발생할 수 있는 오류는 무엇입니까?

Hintsage AI 어시스턴트로 면접 통과

답변

람다 표현식은 하나의 메소드를 구현하는 인터페이스(함수형 인터페이스)의 간결한 문법을 위해 자바 8에 도입되었습니다.

함수형 인터페이스는 정확히 하나의 추상 메소드를 가진 인터페이스입니다. 예:

@FunctionalInterface interface MyAction { void perform(String s); }

람다 표현식은 해당 인터페이스를 구현할 수 있습니다:

MyAction action = (s) -> System.out.println(s); action.perform("Hello lambda!");

람다 표현식을 사용할 때 컴파일러는 어떤 인터페이스가 구현되는지 자동으로 이해합니다(타겟 타입 지정). 람다는 종종 컬렉션과 함께 사용됩니다:

List<String> list = Arrays.asList("one", "two", "three"); list.forEach(s -> System.out.println(s));

함정 질문

질문: 람다 표현식이 외부 클래스의 비정적 필드나 메소드를 참조할 수 있습니까? 이와 관련하여 어떤 제한이 있습니까?

답변: 람다 표현식은 외부 클래스의 필드와 메소드를 참조할 수 있지만, 외부 메소드의 로컬 변수를 사용하는 경우 해당 변수는 final 또는 effectively final (즉, 첫 번째 할당 이후 변경되지 않아야 함)이어야 합니다. 예:

void doIt() { int x = 42; Runnable r = () -> System.out.println(x); // x는 effectively final이어야 함 }

x를 선언 후 변경하면 컴파일 오류가 발생합니다.

주제의 미세한 차이를 모른 채 발생한 실제 오류 사례


이야기

메소드 내에서 람다를 사용할 때 외부 로컬 변수를 변경하려고 시도하여 "람다 표현식에서 사용되는 변수는 final 또는 effectively final이어야 합니다"라는 컴파일 오류가 발생했습니다. 개발팀은 원인을 찾기 위해 많은 시간을 보냈고 이 제한을 기억할 때까지였습니다.


이야기

한 프로젝트에서 사용자 정의 인터페이스를 람다에 사용했지만 @FunctionalInterface로 주석을 다는 것을 잊었습니다. 리팩토링 후 인터페이스에 두 번째 메소드를 추가하여 프로젝트가 컴파일되지 않았습니다. 이는 예기치 않은 오류를 초래했고 이를 찾기가 어려웠습니다.


이야기

람다 표현식을 포함한 객체를 직렬화하려고 시도한 결과 직렬화/역직렬화가 올바르게 작동하지 않았습니다 - 람다는 기본적으로 직렬화되지 않습니다. 람다에 불일치하는 의존성이 포함되어 있다면 네트워크를 통해 전달할 때 오류가 발생할 수 있음을 기억하는 것이 중요합니다.