익명 객체란 ?
익명 객체는 이름이 없는 객체를 말한다. 무명객체라고도 한다.
- 사용 목적 : UI 이벤트 처리 객체 / 스레드 객체를 간편하게 생성하기 위해 많이 활용
- 사용 용도 : 필드 / 로컬변수 의 초기값, 매개변수의 매개값으로 사용
- 사용 조건 : 단독으로 생성 불가, 클래스 상속 or 인터페이스 구현해서 사용 가능 !
- 재사용 목적이 아닌 1번만 사용 하려고 할 때 쓴다.
익명 자식 객체 생성
- 부모 타입으로 필드나 변수를 선언하고, 자식 객체를 초기값으로 대입할 경우
- 우선 부모 클래스를 상속해서 자식 클래스를 선언하고,
- new 연산자를 이용해서 자식 객체를 생성한 후,
- 필드나 로컬 변수에 대입하는 것이 기본이다.
class Child extends Parent { } // 자식 클래스 선언
class A
{
Parent field = new Child(); // 필드에 자식 객체를 대입
void method()
{
Parent localVar = new Child(); // 로컬 변수에 자식 객체를 대입
}
}
그러나 자식 클래스가 재사용되지 않고, 오로지 해당 필드와 변수의 초기값으로만 사용할 경우라면 익명 자식 객체를 생성해서 초기값으로 대입하는 것이 좋은 방법이다.
익명 자식 객체를 생성하는 방법을 다음과 같다. 주의할 점은 하나의 실행문이므로 끝에는 세미콜론(;)을 반드시 붙여야 한다.
Class A
{
Parent field = new Parent()
{
int childField;
void childMethod() {}
@Override
void parentMethod() {}
};
}
- 아래 예제의 경우 부모클래스인 Parent를 상속해서 중괄호 { }; 와 같이 자식 클래스를 선언하라는 뜻
- new 연산자는 이렇게 선언된 자식클래스를 객체로 생성한다.
- 일반 클래스와의 차이점은 생성자를 선언할 수 없다는 것이다.
- 메소드 내에서 로컬 변수를 선언할 때 초기값으로 익명 자식 객체를 생성해서 대입할 수도 있다.
- 또한 메소드의 매개 변수가 부모 타입일 경우 메소드 호출 코드에서 익명 자식 객체를 생성해서 매개값으로 대입할 수도 있다.
public class B
{
void method1(Parent parent) {}
void method2()
{
method1(
new Parent()
{
int childField;
void childMethod() {}
@Override
void parentMethod() {}
}
);
}
}
- 익명 자식 객체에 새롭게 정의된 필드와 메소드는 익명 자식 객체 내부에서만 사용되고, 외부에서는 필드와 메소드에 접근할 수 없다.
- 왜냐하면 익명 자식 객체는 부모 타입 변수에 대입되므로 부모 타입에 선언된 것만 사용할 수 있기 때문이다.
익명 구현 객체 생성
- 인터페이스(interface)에서 구현클래스를 명시적으로 선언하고 사용하는 이유는 재사용성이 높기 때문이다.
- 그러나 쿠현 클래스가 재사용되지 않는다면 익명 구현 객체를 생성해서 사용하는 것이 인적 자원을 줄이는 좋은 방법이다.
- 사용 예시는 아래를 참고 !
public class Button {
OnClickListener listener;
// 매개 변수의 다형성
void setOnClickListener(OnClickListener listener)
{
this.listener = listener;
}
// 구현 객체의 onClock() 메소드 호출
void touch()
{
listener.onClick();
}
// Nested interface
interface OnClickListener
{
void onClick();
}
}
public class Window {
Button button1 = new Button();
Button button2 = new Button();
// 필드 초기값으로 대입
Button.OnClickListener listener = new Button.OnClickListener() {
@Override
public void onClick() {
System.out.println("전화를 겁니다.");
}
};
Window() {
button1.setOnClickListener(listener);
button2.setOnClickListener(new Button.OnClickListener() {
@Override
public void onClick() {
System.out.println("메세지를 보냅니다.");
}
});
}
}
public class Main {
public static void main(String[] args) {
Window w = new Window();
w.button1.touch();
w.button2.touch();
}
}
실행 결과는 아래와 같다.
익명 객체의 로컬 변수 사용
- 익명 객체 내부에서는 바깥 클래스의 필드나 메소드는 제한 없이 사용할 수 있다.
- 문제는 메소드의 매개 변수나 로컬 변수를 익명 개체에서 사용할 때이다.
- 메소드 내에서 생성된 익명 객체는 메소드 실행이 끝나도 힙 메모리에 존재해서 계속 사용할 수 있다.
- 매개 변수나 로컬 변수는 메소드 실행이 끝나면 스택 메모리에서 사라지기 때문에 익명 객체에서 사용할 수 없게 되므로 문제가 발생한다.
- 이 문제에 대한 해결 방법은 로컬클래스의 사용제한과 비슷하다. (final 키워드 관련)
- 익명 클래스의 내부 복사 위치에 신경 쓸 필요 없이 익명 객체에서 사용된 매개 변수와 로컬 변수는 모두 final 특성을 갖는다.
'Coding > Java' 카테고리의 다른 글
[28] JAVA 멀티스레드 (0) | 2022.12.21 |
---|---|
[27] JAVA 기초 복습 (0) | 2022.12.14 |
[25] JAVA 중첩 클래스/ 중첩 인터페이스 (0) | 2022.12.09 |
[24] JAVA 타입 변환과 다형성 (0) | 2022.12.06 |
[23] JAVA 인터페이스 (0) | 2022.12.04 |