ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Java] Chapter 9.2 익명 객체
    Java 2023. 5. 3. 20:58

     

     

    익명 객체의 개요

    익명 객체는 이름이 없는 객체입니다.  익명 객체를 사용하기 위한 조건은 어떤 클래스를 상속하거나 인터페이스를 구현해야 사용할 수 있습니다.  익명 객체를 사용하면 부모 클래스 변수는 이름이 없는 자식 객체를 참조하고, 인터페이스 변수는 이름이 없는 구현 객체를 참조합니다.  

     

    1. [상속]
    부모클래스 변수 = new 부모클래스() {
    	// ...
    };
    2. [구현]
    인터페이스 변수 = new 인터페이스() {
    	// ...
    };



    익명 자식 객체 생성

    익명 자식 객체를 생성하는 방법은 아래와 같습니다.

     부모클래스 [필드|변수] = new 부모클래스(매개값, ---) {
     	// 필드
        // 메소드
    };

     

    자식 클래스가 재사용되지 않고, 특정 위치에서 사용할 경우라면 자식 클래스를 명시적으로 선언하는 것보다는 익명 자식 객체를 생성하는 것이 좋습니다.

     

    부모 클래스(매개값, ...) { ...}

    부모 클래스를 상속해서 중괄호 {} 와 같이 자식 클래스를 선언합니다.  new 연산자는 선언된 자식 클래스를 객체로 생성합니다.

     

    부모 클래스(매개값, ...)

    부모 생성자를 호출하는 코드입니다.  매개값은 부모 생성자의 매개 변수에 맞게 입력합니다.

    중괄호 {} 내부에는 필드나 메소드를 선언하거나 부모 클래스의 메소드를 재정의할 내용을 작성합니다.  일반 클래스와 다르게 생성자를 선언할 수 없습니다.

     

    익명 자식 객체를 생성하는 방법에는 3가지가 있습니다.

     

    1. 필드를 선언할 때 초기값으로 익명 자식 객체를 생성해서 대입합니다.

    class A {
    	// A 클래스의 필드 선언
    	Parent field = new Parent() {
        	int childField;
            void childMethod() { }
            // Parent의 메소드를 재정의
            @Override
            void parentMethod() { }
        };
    }

     

    2. 메소드 내에서 로컬 변수를 선언할 때 초기값으로 익명 자식 객체를 생성해서 대입합니다.

    class A {
    	void method() {
        	Parent localVar = new Parent() {
            	int childField;
                void childMethod() { }
                @Override
                void parentMethod() { }
            };
        }
    }

     

    3. 메소드의 매개 변수가 부모 타입일 경우 메소드를 호출하는 코드에서 익명 자식 객체를 생성해서 매개값으로 대입합니다.

    class A {
    	void method1(Parent parent) { }
        
        void method2() {
        	// method1() 메소드 호출
        	method1(
            // method1()의 매개값으로 익명 자식 객체를 대입
            	new Parent() {
                	int childField;
                    void childMethod() { }
                    @Override
                    void parentMethod() { }
                }
           };
        }
    }

     

    익명 자식 객체에 새롭게 정의된 필드와 메소드는 익명 자식 객체 내부에서만 사용되고, 외부에서는 접근할 수 없습니다.  익명 자식 객체는 부모 타입 변수에 대입되므로 부모 타입에 선언된 것만 사용할 수 있기 때문이다.

     

     

    익명 구현 객체 생성

    익명 구현 객체를 생성하는 방법은 다음과 같습니다.

    인터페이스 [필드|변수] = new 인터페이스() {
    	// 인터페이스에 선언된 추상 메소드의 실체 메소드 선언
        // 필드
        // 메소드
    }

     

    구현 클래스가 재사용되지 않고, 특정 위치에서 사용할 경우라면 구현 클래스를 명시적으로 선언하는 것보다는 익명 구현 객체를 생성하는 것이 좋습니다.

     

    인터페이스() { ... }

    인터페이스를 구현해서 중괄호 {}와 같이 클래스를 선언합니다.  new 연산자는 선언된 구현 클래스를 객체로 생성합니다.  중괄호 {}에는 인터페이스에 선언된 모든 추상 메소드의 실체 메소드를 재정의해야 합니다.

     

    익명 구현 객체를 생성하는 방법에는 3가지가 있습니다.

     

    1. 필드를 선언할 때 초기값으로 익명 구현 객체를 생성해서 대입합니다.

    class A {
    	// 클래스 A의 필드 선언
    	RemoteControl field = new RemoteControl() {
        	// RemoteControl 인터페이스의 추상 메소드에 대한 실체 메소드
        	@Override
            void turnOn() { }
        };
    }

     

    2. 메소드 내에서 로컬 변수를 선언할 때 초기값으로 익명 구현 객체를 생성해서 대입합니다. 

    void method() {
    	// 로컬 변수 선언
    	RemoteControl localVar = new RemoteControl() {
        	// RemoteControl 인터페이스의 추상 메소드에 대한 실체 메소드
        	@Override
            void turnOn() { }
        };
    }


    3. 메소드의 매개 변수가 인터페이스 타입일 경우 메소드를 호출하는 코드에서 익명 구현 객체를 생성해서 매개값으로 대입합니다.

    class A {
    	void method1(RemoteControl rc) { }
        
        void method2() {
        	// method1() 메소드 호출
        	method1(
            	// method1()의 매개값으로 익명 구현 객체를 대입
            	new RemoteControl() {
                	@Override
                    void turnOn() { }
                }
            );
        }
    }

     

    익명 객체의 로컬 변수 사용

    메소드의 매개 변수나 로컬 변수를 익명 객체 내부에서 사용할 때 제한이 있습니다.  익명 객체는 메소드 실행이 종료되면 없어지는 것이 일반적이지만, 메소드가 종료되어도 계속 실행 상태로 존재할 수 있습니다.

    메소드의 매개 변수나 로컬 변수를 익명 객체 내부에서 사용했을 때 문제가 발생합니다.  매개 변수나 로컬 변수는 메소드 실행이 끝나면 스택 메모리에서 사라지기 때문에 익명 객체에서 지속적으로 사용할 수 없습니다.

     

    이 문제를 해결하기 위해 컴파일 시 익명 객체에서 사용하는 매개 변수나 로컬 변수의 값을 익명 객체 내부에 복사해두고 사용합니다.  따라서 매개 변수나 로컬 변수가 수정되어 값이 변경되면 익명 객체에 복사해 둔 값과 달라지므로 매개 변수나 로컬 변수에는 final를 선언해야합니다.

     

    * 자바 7 버전 이후로는 매개 변수와 로컬 변수에 final 키워드가 자동으로 부여됩니다. 

     

    출처 | 혼자 공부하는 자바

Designed by Tistory.