익명 클래스(Anonymous Class)
자바의 익명 클래스는 이름이 없는 클래스이다.
익명 클래스는 클래스 정의와 동시에 객체를 생성하며, 해당 객체는 일회성으로만 사용된다.
(※ 일회성이기 때문에 메모리 관리에서 효과적이다.)
다음은 Subject 클래스를 상속받아 즉석에서 익명 클래스로 구현한 예제이다.
이 익명 클래스(코드 블록)는 Subject의 exam() 메소드를 오버라이딩한 뒤, english로 할당되었다.
class Subject {
public void exam() {
System.out.println("시험을 봅니다.");
}
}
public class Anonymous {
public static void main(String[] args) {
Subject english = new Subject() {
@Override
public void exam() {
System.out.println("영어 시험을 봅니다.");
}
};
english.exam(); // 영어 시험을 봅니다.
}
}
익명 클래스는 위처럼 상속할 수 있는 모든 클래스나 구현할 수 있는 모든 인터페이스를 대상으로 생성될 수 있다.
인터페이스로 익명 클래스를 만드는 예시도 살펴보고 넘어가자.
interface Order {
public String confirm();
public String cancel();
}
public class Anonymous {
public static void main(String[] args) {
Order computerOrder = new Order() {
@Override
public String confirm() {
return "컴퓨터 주문";
}
@Override
public String cancel() {
return "컴퓨터 주문 취소";
}
};
System.out.println(computerOrder.confirm()); // 컴퓨터 주문
System.out.println(computerOrder.cancel()); // 컴퓨터 주문 취소
}
}
Order 인터페이스는 주문하고, 주문을 취소할 수 있는 confirm(), cancel() 메소드를 가지고 있다.
익명 클래스는 인터페이스를 구현해 오버라이딩하여 computerOrder 변수로 할당하였다!
익명 클래스는 변수로 할당할 수도 있지만, 함수의 인자나 반환값에도 사용할 수 있다.
함수의 인자와 반환값으로 익명 클래스를 사용하는 경우는 다음과 같다.
interface Calculator {
int operate(int a, int b);
}
public class Anonymous {
static void add(Calculator calc) {
int result = calc.operate(3, 4);
System.out.println(result); // 7
}
public static void main(String[] args) {
// 1. 익명 클래스를 함수의 인자로 전달
add(new Calculator() {
@Override
public int operate(int a, int b) {
return a + b;
}
});
Calculator multiply = getOperation("*");
System.out.println(multiply.operate(3, 5)); // 15
}
// 2. 익명 클래스를 함수의 반환 값으로 전달
static Calculator getOperation(String op) {
return new Calculator() {
@Override
public int operate(int a, int b) {
switch (op) {
case "+": return a + b;
case "-": return a - b;
case "*": return a * b;
case "/": return b != 0 ? a / b : 0;
default: return 0;
}
}
};
}
}
add()의 인자와 getOperation()의 반환값으로
⇒ Calculator 인터페이스의 구현체를 대신해 익명 클래스를 구현하여 전달하였다.
💡 익명 클래스는 상속과 구현이 필요하지만, extends나 implements로 별도의 하위 클래스를 정의하고 싶지 않을 때 !!
또한, 한 번만 사용하고 싶을 때 편리하게 사용할 수 있다.
람다식(Lambda Expression)
람다식은 익명 함수를 더 간단히 표현할 수 있는 방식이다.
람다 함수의 사용법은 다음과 같다.
// 익명 클래스
Runnable r1 = new Runnable() {
@Override
public void run() {
System.out.println("I'm a Anonymous.");
}
};
// 람다식
Runnable r2 = () -> System.out.println("I'm a Lambda.");
-> 화살표를 기준으로 왼쪽에는 함수의 인자값, 오른쪽에는 인자값을 활용하는 식이나 동작을 한 줄로 표현한다.
❗️ 람다식을 사용할 때 주의할 점은 SAM(Single Abstract Method)에서만 쓸 수 있다는 것이다.
💡 SAM(Single Abstract Method)
SAM은 단 하나의 추상 메소드만 있는 추상 클래스 혹은 함수형 인터페이스를 의미한다.
함수형 인터페이스와 이를 람다식으로 구현한 예제는 다음과 같다.
interface Calculator {
int operate(int a, int b);
}
public class Lambda {
public static void main(String[] args) {
Calculator add = (a, b) -> a + b;
Calculator sub = (a, b) -> a - b;
System.out.println(add.operate(10, 5)); // 15
System.out.println(sub.operate(10, 5)); // 5
}
}
Calculator는 추상 메소드가 하나(operate()) 있는 함수형 인터페이스이다.
람다식을 구현하기 위해서는 인터페이스에 다른 메소드가 더 들어올 수 없다!
추상 클래스 또한 추상 메소드가 하나라면 람다식으로 구현할 수 있다.
이로써 익명 클래스와 람다식에 대해 알아보았다.
둘은 함수를 간결하게 표현하기 위한 함축적인 방식이지만, 사용 가능한 조건과 세부 구현 방식에 차이가 있다.!
요약
익명 클래스: 인터페이스, 클래스의 하위 기능을 일회용으로 가져다 쓰기 위함.
람다식: SAM을 일회용으로 가져다 쓰기 위함.
변수 할당, 함수의 인자 및 반환값으로 익명 클래스와 람다식을 쓸 수 있음. (by 오버라이딩)
👏
참고
'Java' 카테고리의 다른 글
| [Java] JDK / JRE / JVM (1) | 2026.01.18 |
|---|---|
| [Java] Reflection (0) | 2025.10.23 |
| [Java] 제네릭(Generic) (0) | 2025.10.06 |
| [Java] 인터페이스 vs 추상 클래스 (0) | 2025.10.03 |
| [Java] final vs static vs static final (0) | 2025.09.22 |