JDK 1.8부터 추가된 문법으로 메서드를 하나의 식으로 표현할 수 있게 해준다. 람다식의 원리는 익명 객체다. 컴파일러가 해당 식을 읽어 익명 객체로 만든 뒤 활용하게 해준다.
람다식을 사용하기 위해서는 추상 메서드가 하나 존재하는 인터페이스를 생성해야한다. 이를 함수형 인터페이스(FunctionalInterface)라고 한다.
static 메서드와 default 메서드의 개수에는 제약이 없다.
@FunctionalInterface
interface Sample{
void hi();
}
public class Main {
public static void main(String[] args){
Sample s = () -> {
System.out.println("hi");
};
s.hi();
}
}
해당 인터페이스 타입의 변수를 생성하여 람다식을 넣을 수가 있다.
프로그램을 실행하면, s
에는 Sample
인터페이스를 구현한 익명 객체가 저장된다. 이를 이용해 메서드를 실행할 수 있다.
@FunctionalInterface
interface Sample{
int cal(int a, int b);
}
public class Main {
public static void main(String[] args){
Sample s = (a, b) -> {
return a * b;
};
/*
아래도 가능
Sample s = (int a, int b) -> {
return a * b;
};
*/
System.out.println(s.cal(1, 2));
}
}
위와 같이 인자를 받을 수도 있다.
@FunctionalInterface
interface Sample{
int cal(int a);
}
public class Main {
public static void main(String[] args){
Sample s = a -> {
return a * a * a;
};
System.out.println(s.cal(2));
}
}
추상 메서드의 인자가 하나라면 괄호도 생략이 가능하다.
Thread
클래스의 생성자로 사용할 수 있다.
public class Main {
public static void main(String[] args){
Thread t1 = new Thread(() -> System.out.println("hi"));
t1.start();
}
}
이것이 가능한 이유는, Thread
클래스는 Runnable
인터페이스를 생성자로 받을 수 있기 때문이다.
public Thread(Runnable target) {
this(null, target, "Thread-" + nextThreadNum(), 0);
}
그리고 Runnable
인터페이스는 다음과 같이 이루어져 있다.
@FunctionalInterface
public interface Runnable {
/**
* When an object implementing interface <code>Runnable</code> is used
* to create a thread, starting the thread causes the object's
* <code>run</code> method to be called in that separately executing
* thread.
* <p>
* The general contract of the method <code>run</code> is that it may
* take any action whatsoever.
*
* @see java.lang.Thread#run()
*/
public abstract void run();
}
즉 함수형 인터페이스이기 때문에 가능하다.
이 외에도 다양한 클래스에서 활용 가능하다.