JAVA의 가장 기본이 되는 내용

익명 클래스

cwchoiit 2024. 4. 21. 18:33
728x90
반응형
SMALL

참고자료:

 

김영한의 실전 자바 - 중급 1편 | 김영한 - 인프런

김영한 | 실무에 필요한 자바의 다양한 중급 기능을 예제 코드로 깊이있게 학습합니다., 국내 개발 분야 누적 수강생 1위, 제대로 만든 김영한의 실전 자바[사진][임베딩 영상]단순히 자바 문법을

www.inflearn.com

 

익명 클래스는 마찬가지로 중첩 클래스의 일종이다.

익명 클래스는 이름 그대로 이름이 없는 클래스를 의미하는데, 저번 지역 클래스에서 사용했던 코드를 가져와서 익명 클래스로 변경해보자.

 

package nested.local;

import java.lang.reflect.Field;

public class OuterClass {

    private int outerInstanceVar = 10;
    private static int outerClassVar = 100;

    public LocalClazzInterface process(int paramVar) {
        int localVal = 2;

        class LocalClazz implements LocalClazzInterface {
            private int localInstanceVal = 5;

            @Override
            public void print() {
                System.out.println("localInstanceVal = " + localInstanceVal);
                System.out.println("localVal = " + localVal);
                System.out.println("paramVar = " + paramVar);
                System.out.println("outerInstanceVar = " + outerInstanceVar);
                System.out.println("outerClassVar = " + outerClassVar);
            }
        }

        return new LocalClazz();
    }

    public static void main(String[] args) {
        OuterClass outerClass = new OuterClass();
        LocalClazzInterface localClazz = outerClass.process(1);

        localClazz.print();

        Field[] declaredFields = localClazz.getClass().getDeclaredFields();
        for (Field declaredField : declaredFields) {
            System.out.println("declaredField = " + declaredField);
        }
    }
}

 

이 소스에서 LocalClazzInterface를 구현한 지역 클래스 LocalClazz를 익명 클래스로 변경할 수 있다.

 

AnonymousClass

package nested.local;

import java.lang.reflect.Field;

public class AnonymousClass {

    private int outerInstanceVar = 10;
    private static int outerClassVar = 100;

    public LocalClazzInterface process(int paramVar) {
        int localVal = 2;

        LocalClazzInterface localClazz = new LocalClazzInterface() {
            private int localInstanceVal = 5;
            @Override
            public void print() {
                System.out.println("localInstanceVal = " + localInstanceVal);
                System.out.println("localVal = " + localVal);
                System.out.println("paramVar = " + paramVar);
                System.out.println("outerInstanceVar = " + outerInstanceVar);
                System.out.println("outerClassVar = " + outerClassVar);
            }
        };

        System.out.println("localClazz.getClass() = " + localClazz.getClass());

        return localClazz;
    }

    public static void main(String[] args) {
        AnonymousClass outerClass = new AnonymousClass();
        LocalClazzInterface localClazz = outerClass.process(1);

        localClazz.print();

        Field[] declaredFields = localClazz.getClass().getDeclaredFields();
        for (Field declaredField : declaredFields) {
            System.out.println("declaredField = " + declaredField);
        }
    }
}

실행결과:

localClazz.getClass() = class nested.local.AnonymousClass$1
localInstanceVal = 5
localVal = 2
paramVar = 1
outerInstanceVar = 10
outerClassVar = 100
declaredField = private int nested.local.AnonymousClass$1.localInstanceVal
declaredField = final int nested.local.AnonymousClass$1.val$localVal
declaredField = final int nested.local.AnonymousClass$1.val$paramVar
declaredField = final nested.local.AnonymousClass nested.local.AnonymousClass$1.this$0

 

process() 메서드 내부를 보면, LocalClazzInterface 라는 인터페이스에 new라고 새로 생성하는 것처럼 보이는데 인터페이스를 인스턴스로 만드는 게 아니라 인터페이스를 구현하는 구현체를 만들어내는 것이다. 근데 따로 클래스를 정의해서 구현하는게 아니고 바로 생성해내는 방식을 익명클래스라고 한다.

 

그러니까 쉽게 말해 지역클래스에 대한 선언과 생성을 한번에 한다고 보면 된다.

 

익명 클래스 특징

  • 익명 클래스는 이름 없는 지역 클래스를 선언하면서 동시에 생성한다.
  • 익명 클래스는 부모 클래스를 상속 받거나, 또는 인터페이스를 구현해야 한다. 익명 클래스를 사용할 때는 상위 클래스나 인터페이스가 필요하다.
  • 익명 클래스는 말 그대로 이름이 없다. 이름을 가지지 않으므로 생성자를 가질 수 없다. (기본 생성자만 사용됨)
  • 익명 클래스는 위 실행결과의 AnonymousClass$1 과 같이 자바 내부에서 바깥 클래스 이름 + $ + 숫자로 정의된다. 익명 클래스가 여러개면 $1, $2, $3 으로 숫자가 증가하면서 구분된다.

익명 클래스의 장점

익명 클래스를 사용하면 클래스를 별도로 정의하지 않아도 인터페이스나 추상 클래스를 즉석에서 구현할 수 있어 코드가 더 간결해진다. 하지만 복잡하거나 재사용이 필요한 경우에는 별도의 클래스를 정의하는 것이 좋다.

 

익명 클래스를 사용할 수 없을 때

익명 클래스는 단 한 번만 인스턴스를 생성할 수 있다. 다음과 같이 여러 번 생성이 필요하다면 익명 클래스를 사용할 수 없다. 대신에 지역 클래스를 선언하고 사용하면 된다. 

LocalClazz localClazz1 = new LocalClazz();
localClazz1.print();

LocalClazz localClazz2 = new LocalClazz();
localClazz2.print();

 

익명 클래스 정리

  • 익명 클래스는 이름이 없는 지역 클래스이다.
  • 특정 부모 클래스(인터페이스)를 상속 받고 바로 생성하는 경우 사용한다.
  • 지역 클래스가 일회성으로 사용되는 경우나 간단한 구현을 제공할 때 사용한다.

 

728x90
반응형
LIST