✏️ 익명 클래스란?
- 이름이 없는 클래스 → 별도의 클래스 파일을 만들지 않고, 코드 내에서 일회성으로 정의하여 사용하기 때문
- 인터페이스나 추상 클래스를 구현할 때 즉석에서 한 번만 쓰고 버릴 목적으로 사용
💡 인터페이스를 활용한 익명 클래스 예제
public interface Calculator {
int sum(int a, int b);
}
public class Main {
public static void main(String[] args) {
// ✅ 익명 클래스 활용
Calculator calculator1 = new Calculator() {
@Override
public int sum(int a, int b) {
return a + b;
}
};
int ret1 = calculator1.sum(1, 1);
System.out.println("ret1 = " + ret1);
}
}
🧠 람다란?
- 익명 함수를 표현하는 방식
- 즉, 메서드 이름 없이 일회용으로 동작을 정의하고, 이를 함수형 인터페이스에 전달하는 문법
✅ 기본 문법
(매개변수) -> { 실행문; }
| 형태 | 예시 | 설명 |
|---|---|---|
| 매개변수 없음 | () -> System.out.println("Hello") | 인자 없는 함수 |
| 매개변수 1개 | x -> x * x | 괄호 생략 가능 |
| 매개변수 여러 개 | (x, y) -> x + y | 괄호 필요 |
| 코드 한 줄 | x -> x + 1 | 중괄호 생략 가능 |
| 코드 여러 줄 | x -> { int y = x + 1; return y * 2; } | 중괄호와 return 필요 |
⚠️ 람다 사용 시 주의 사항
반드시 함수형 인터페이스 활용
→ 인터페이스에 두 개 이상의 추상 메서드가 존재하면 컴파일러가 어떤 메서드를 구현하는지 모호해지기 때문
ex) 오버로딩(Overloading) 기능을 통해 같은 이름의 sum() 메서드를 여러 형태로 정의한다면, 람다 표현식이 어떤 메서드를 구현하는 것인지 명확하지 않아 모호성이 발생할 수 있음
🗒️ 예시 코드:
public interface Calculator {
int sum(int a, int b); // ✅ 선언 가능
int sum(int a, int b, int c); // ⚠️ 오버로딩으로 선언 가능 모호성 발생!
}
@FunctionalInterface // ✅ 함수형 인터페이스 선언
public interface Calculator {
int sum(int a, int b); // ✅ 오직 하나의 추상 메서드만 선언해야 함
int sum(int a, int b, int c); // ❌ 선언 불가 에러 발생!
}
📚 람다식을 매개변수로 전달하는 방법
public class Main {
public static int calculate(int a, int b, Calculator calculator) {
return calculator.sum(a, b);
}
public static void main(String[] args) {
Calculator cal1 = new Calculator() {
@Override
public int sum(int a, int b) {
return a + b;
}
};
// ✅ 익명 클래스를 변수에 담아 전달
int ret3 = calculate(3, 3, cal1);
System.out.println("ret3 = " + ret3); // 출력: ret3 = 6
}
}
calculate() 메서드의 매개변수 타입으로 Calculator 인터페이스를 구현했는지 추론되기 때문에 람다식 전달 가능public class Main {
public static int calculate(int a, int b, Calculator calculator) {
return calculator.sum(a, b);
}
public static void main(String[] args) {
Calculator cal2 = (a, b) -> a + b;
// ✅ 람다식을 변수에 담아 전달
int ret4 = calculate(4, 4, cal2);
System.out.println("ret4 = " + ret4); // 출력: ret4 = 8
}
}
calculate() 메서드의 매개변수 타입으로 Calculator 인터페이스를 구현했는지 추론됨public class Main {
public static int calculate(int a, int b, Calculator calculator) {
return calculator.sum(a, b);
}
public static void main(String[] args) {
// ✅ 람다식을 직접 매개변수로 전달
int ret5 = calculate(5, 5, (a, b) -> a + b);
System.out.println("ret5 = " + ret5); // 출력: ret5 = 10
}
}
🎯 익명 클래스와 람다의 차이점
| 항목 | 익명 클래스 | 람다 |
|---|---|---|
| 문법 | 비교적 장황 | 매우 간결 |
| 대상 | 모든 인터페이스/추상클래스 | 함수형 인터페이스만 가능 |
this | 자기 자신을 가리킴 | 외부 객체를 가리킴 |
| 가독성 | 낮음 | 높음 |
| 사용 예 | 복잡한 구현 필요할 때 | Runnable, Comparator, Stream 등 |
| 메서드 개수 | 여러 개 가능 | 추상 메서드 하나만 가능 |