티스토리 뷰
콜백 함수는 함수의 인자로 다른 함수를 받아서 실행되는 함수를 말한다.
보통 핸들러 함수를 구현할 때 많이 사용하는 개념이다.
이렇게, 함수를 다른 함수의 인자로 전달하려면 특정 조건을 만족해야 하는데, 그것은 바로 함수가 "일급 객체"이어야 한다는 점이다.
# 일급 객체
- 변수에 할당 가능
- 함수 인자로 전달 가능 (콜백 함수)
- 리턴 값으로 지정 가능
함수가 일급 객체인 언어는 보통 동적 언어들이다.
정적 언어 = 변수 타입을 미리 선언해서 사용하는 언어들 (C++, Java)
동적 언어 = 변수 타입을 따로 선언 안 해도 실행 도중 알아서 타입이 매치되는 언어들 (Python, JavaScript)
Java의 함수는 일급 객체?
우선, Java의 함수는 일급 객체가 아니다.
왜냐하면 일급 객체의 조건을 단 하나도 만족하지 않기 때문이다.
1. 변수에 할당 가능한가?
2. 함수 인자로 전달 가능한가?
3. 리턴 값으로 함수 가능한가?
마찬가지로 함수 타입이 없기 때문에 안된다.
최상위 Object 클래스로 받으면 어떨까? 그래도 안된다.
근본적인 원인은 Java에서 함수 타입을 지원하지 않기 때문이다.
Java의 트릭, 람다식과 함수형 인터페이스
하지만, 우리는 Java를 공부하면서, 또는 사용하면서 함수 인자에 마치 다른 함수를 전달한 것 같은 문법을 자주 봤을 것이다.
public static void main(String[] args) {
ArrayList<Integer> arr = new ArrayList<>(Arrays.asList(1,2,3,4));
arr.forEach(n -> System.out.println(n));
}
Java의 함수는 일급 객체가 아니라 인수로 전달이 불가능한데, 어떻게 저기에는 함수가 들어가 있는 것일까??
이는 사실, 인자로 함수를 전달한 게 아니라 추상 메서드가 하나인 인터페이스를 전달함으로써 인자 내부에서 추상 메서드를 구현하게끔 꼼수를 쓴 것이다.
이 개념을 "함수형 인터페이스"라고 부르는데, Java 8 업데이트에서 Stream과 같이 추가되었다.
궁금증
비슷한 객체 지향 정적 언어인 C++은 업데이트를 통해 함수를 일급 객체처럼 다룰 수 있게 되었다.
그렇다면 왜 Java는 함수를 일급 객체로 설정하지 않고 함수형 인터페이스를 도입하면서 람다식으로 구현했을까?
무언가 Side-Effect가 있어서 그런 것일까, 궁금하다.
재밌게도 동일한 JVM 위에서 구동되는 Java 사촌뻘 Kotlin의 함수는 일급 객체다.