익명클래스는 아래의 다이어그램에서 보듯이 일종의 중첩클래스이다.
(참조: https://www.baeldung.com/java-anonymous-classes)
익명클래스는 다른 내부클래스들과 달리 이름을 갖지 않으며 사용하는 시점에 선언과 함께 초기화를 해줘야한다.
기존에 있는 클래스를 상속받거나 인터페이스를 구현하여 익명클래스를 사용할 수 있다. 아래의 예제를 보자.
public class HelloWorldAnonymousClasses {
interface HelloWorld {
public void greet();
public void greetSomeone(String someone);
}
public void sayHello() {
// 로컬 클래스
class EnglishGreeting implements HelloWorld {
String name = "world";
public void greet() {
greetSomeone("world");
}
public void greetSomeone(String someone) {
name = someone;
System.out.println("Hello " + name);
}
}
HelloWorld englishGreeting = new EnglishGreeting();
HelloWorld frenchGreeting = new HelloWorld() {
String name = "tout le monde";
public void greet() {
greetSomeone("tout le monde");
}
public void greetSomeone(String someone) {
name = someone;
System.out.println("Salut " + name);
}
};
englishGreeting.greet();
frenchGreeting.greet();
}
public static void main(String... args) {
HelloWorldAnonymousClasses myApp =
new HelloWorldAnonymousClasses();
myApp.sayHello();
}
}
위의 예제 HelloWorldAnonymousClasses에서 지역 변수는 frenchGreeting을 초기화할 때 익명클래스를 사용한다. 보다시피 이름이 없고 new InterfaceName(){...}
혹은 new ParentClass(...){...}
와 같은 문법으로 구현하게 된다.
또한 익명클래스는 하나의 표현식(expression)이기 때문에 statement의 한 파트이다. 그러므로 끝에 세미콜론을 넣어서 statement를 끝내줘야 한다.
생성 도중 익명클래스의 객체는 정확히 하나만 존재한다. 그러므로 abstract가 될 수 없다. 이름이 없어서 extend 할 수도 없다. 같은 이유로 익명클래스는 명시적으로 선언된 생성자를 가질 수 없다.
상수를 제외한 static멤버를 가질 수 없다.
다른 이너클래스처럼 익명클래스도 자신을 둘러싼 클래스 내의 모든 멤버에 접근가능하다.
- 하지만 지역 변수는 반드시 final로 선언되어 있거나 effectively final 이어야 한다. effectively final이란 변수가 초기화된 이후 값이 한번도 변경되지 않았을 경우를 말한다.
주로 UI 이벤트 처리나 스레드 객체를 생성할 때 처럼 프로그램 내에서 일시적으로 사용하는 객체의 경우 익명클래스를 사용한다.
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
...
}
}
https://www.baeldung.com/java-anonymous-classes
https://limkydev.tistory.com/226