본문 바로가기
Java

Java 중급 1 - 중첩클래스, 내부 클래스(4)

by KongJiHoon 2025. 4. 21.

1. 익명 클래스(Anonymous Class)

  • 익명 클래스란?
    • 익명 클래스(Anonymous Class)는 이름이 없는 지역 클래스(Local Class)의 한 종류이다. 인터페이스나 추상 클래스를 바로 구현하고 객체로 만들 수 있는 간단한 방법이다.
Printer printer = new Printer() {
    @Override
    public void print() {
        System.out.println("익명 클래스 구현체");
    }
};

 

  • Printer는 인터페이스
  • new Printer() { ... }는 익명 클래스 선언 + 생성을 동시에 처리
항목 지역 클래스 익명 클래스
이름 있음 없음
생성자 사용 가능 불가능
재사용 가능 단 1회 사용
가독성 복잡해질 수 있음 간결
목적 로직 재사용 즉석에서 간단한 구현

 

 

예제 코드1

Printer printer = new Printer() {
    int value = 0;

    @Override
    public void print() {
        System.out.println("value = " + value);
        System.out.println("localVar = " + localVar);
        System.out.println("paramVar = " + paramVar);
        System.out.println("outInstanceVar = " + outInstanceVar);
    }
};

printer.print();

 

  • Printer 인터페이스를 구현한 클래스의 이름 없이 객체를 생성
  • 필드, 메서드 구현 모두 가능
  • 내부적으로는 Outer$1 같은 이름으로 컴파일됨

 

익명 클래스의 주요 특징

 

  • 이름 없음
    • 클래스 선언과 객체 생성을 한 번에 함
  • 생성자 정의 불가
    • 클래스 이름이 없기 때문에 생성자도 없다
  • 인터페이스나 추상 클래스만 상속/구현 가능
  • 한 번만 사용 가능
    • 두 번 이상 객체를 만들고 싶다면 지역 클래스나 일반 클래스를 써야 함
  • 내부적으로 자동 이름 지정
    • 컴파일 시 Outer$1, Outer$2 같은 형식

 

예제코드 2 -> 리펙토링 전

 

package practice.anonymous.ex;

import java.util.Random;

public class Ex1Main {

    public static void hello(Process process) {

        System.out.println("프로그램 시작");

        process.run();

        System.out.println("프로그램 종료");
    }



    public static class Dice implements Process {


        @Override
        public void run() {
            int dice = new Random().nextInt(6) + 1;
            System.out.println(dice);
        }


    }

    public static class Sum implements Process {


        @Override
        public void run() {
            for (int i = 0; i < 3; i++) {
                System.out.println("i = " + i);
            }
        }
    }





    public static void main(String[] args) {
        hello(new Dice());
        hello(new Sum());
    }


}

 

 

 

리펙토링 후

 

package practice.anonymous.ex;

import java.util.Random;

public class Ex3Main {

    public static void hello(Process process) {

        System.out.println("프로그램 시작");

        process.run();

        System.out.println("프로그램 종료");
    }






    public static void main(String[] args) {

        hello(new Process() {


            @Override
            public void run() {
                int dice = new Random().nextInt(6) + 1;
                System.out.println(dice);
            }


        });
        hello(new Process() {


            @Override
            public void run() {
                for (int i = 0; i < 3; i++) {
                    System.out.println("i = " + i);
                }
            }
        });


    }


}

 

  • hello() 메서드에 Process 구현체를 직접 전달
  • 코드 조각을 외부로부터 인수 형태로 받아 재사용성 향상

 

주의할 점

  • 익명 클래스는 한 번만 사용 가능
    → 여러 번 재사용할 로직이면 일반 클래스나 지역 클래스를 써야 함
  • 람다(Lambda)와 구분해야 함
    → 람다는 함수형 인터페이스만 사용할 수 있음

 

 

정리

  • 익명 클래스는 인터페이스나 추상 클래스를 즉석에서 구현하고 한 번만 객체 생성할 때 사용
  • 코드가 간결해지고 일회성 로직 처리에 유리
  • 하지만 복잡하거나 재사용이 필요한 경우에는 적절하지 않음

 

*** 람다 표현식(Lambda Expression) ***

  • 람다(lambda)는 익명 함수를 간결하게 표현하는 방법
  • 자바 8부터 도입되었고, 주로 함수형 인터페이스(Functional Interface)를 구현할 때 사용
package practice.anonymous.ex;

import java.util.Random;

public class Ramda {

    public static void hello(Process process) {

        System.out.println("프로그램 시작");

        process.run();

        System.out.println("프로그램 종료");
    }






    public static void main(String[] args) {

        hello(() -> {
            int dice = new Random().nextInt(6) + 1;
            System.out.println(dice);
        });


        hello(() -> {
            for (int i = 0; i < 3; i++) {
                System.out.println("i = " + i);
            }
        });


    }


}

 

 

출처 : 인프런 중급 1편 - 김영한