본문 바로가기

JAVA 골뱅이는 뭐임?

@Salieri2025. 10. 1. 14:56

Java에서 Annotation (@) 은 기본적으로 "메타데이터(metadata)" 라고 할 수 있다.

 

혹여나 메타데이터가 뭔지 모르는 코붕이(코드 뉴비라는 뜻 ㅋㅋ) 를 위해 설명을 한다면, 

"데이터에 대한 데이터" 라고 보면 된다.
즉, 원래 데이터 자체가 아니라 그 데이터를 설명하는 정보인 샘 

 

사람의 이름으로 한다면, "김덕배" 의 생일은 메타데이터라고 할 수 있다. 그러니까, 책이라고 한다면 책의 ISBN을 메타데이터라고 할 수 있고. 데이터를 설명하는 데이터라고 생각하면 이해하기 쉬운데. 더 헷갈리는 사람들을 위해 네이버 사전을 인용한다면 

이라고 말한다

 

 

 

말 그대로 "코드에 붙이는 주석/메모" 같은 개념인데,

단순히 주석처럼 무시되는 건 아니고 컴파일러나 런타임 환경이 해석할 수 있는 데이터이다.

 

 

 

그러면 훌륭한 우리 뉴비 친구들은 ?

 

앵? 그러면 아무거나 적어서 @달면 되는거 아니냐? 주석이랑은 무슨 차이지? 

 

이라고 답을 할 수가 있는데, "주석"의 목적은 "읽는 '사람'"을 위한 것이라면 @이라는 Annotation 는 당신이 코드를 쓰고 있는 컴파일러가 이해할 수 있도록 머리에 달아주는 것을 말한다. 이것도 만약에 헷갈리면, 컴파일러의 개념이 부족한 것인데, 관련 컴파일러에 대한 이야기는 정말 길어지니 포스팅은 또 다음에 따로 하겠다


🔹 Annotation의 기본 특징

  • 아무 프레임워크도 없이 쓰면:
    • @Override, @Deprecated, @SuppressWarnings 같은 표준 애노테이션컴파일러가 직접 해석한다.
      • @Override → 메서드 오버라이드가 제대로 되었는지 컴파일러 체크
      • @Deprecated → 사용 시 경고 표시
      • @SuppressWarnings → 컴파일 경고 억제
    이런 건 "단순 메모" 이상으로, 컴파일 단계에서 동작에 영향을 준다.
  • 런타임까지 가져가려면:
    • 애노테이션 정의 시 @Retention(RetentionPolicy.RUNTIME) 을 붙이면 Reflection으로 읽을 수 있다.
    • 이 경우, 프레임워크 없이도 Class.getAnnotations() 같은 방식으로 직접 해석 가능은 하다.
public class Test {
    @내맘대로적음 // ❌ 사람 : ㅇㅇ 이 사람은 내 맘대로 적었구나 컴파일러 : ??? 님 이게 머에요? 
    public void doSomething() {
        System.out.println("Hello");
    }
}

 

이렇게 하면 컴파일러가 : ㅇ? 이게 진짜 모에요? 라고 오류를 뱉어낼 것이다 

error: cannot find symbol
    @내맘대로적음
     ^
  symbol:   class 내맘대로적음

 

이것은 코드가 "내가 님 코드 읽어보고 실행할려고 했는데 이게 먼지 몰라서 일단 실행안할게요" 라고 답하는 것이다 

 


🔹 이제 프레임워크가 있으면

Spring, Hibernate 같은 프레임워크는 이 애노테이션을 런타임에 해석해서 동작을 바꿈
예:
  • @Autowired → 객체 주입
  • @Entity → JPA 엔티티로 인식
  • @Controller → 웹 컨트롤러로 등록
즉, 프레임워크가 Annotation을 읽고 “행동을 연결”해주기 때문에
애노테이션이 단순한 메모를 넘어서 실행 흐름까지 제어하게 된다

 

 

그럼에도 불구하고 내가 사용하고 정의 하는대로 쓰게 하고 싶다면??

  • 애노테이션은 클래스처럼 “정의” 되어 있어야 한다
  • @Override 같은 애들은 사실 자바 표준 라이브러리에 @interface Override { ... } 로 정의된 애노테이션이거든요.
  • 정의되지 않은 이름의 애노테이션을 쓰면 “심볼을 찾을 수 없다” 라는 컴파일 에러가 발생

 

내가 그럼 직접 정의를 해보자

import java.lang.annotation.*;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface 내맘대로적음 {
    String value() default "no message";
}

 

이제 정의를 했으니까, Java Class 를 통해  Class 를 정의 해보자 

 

public class MyService {

    @내맘대로적음("이 메서드는 중요한 작업을 한다")
    public void doWork() {
        System.out.println("열심히 일하는 중...");
    }

    @내맘대로적음
    public void doNothing() {
        System.out.println("아무것도 안 하는 중...");
    }
}
 

 

그럼 이제 void main 에서 갖고 놀기 시작을 해보면 

 

import java.lang.reflect.Method;

public class AnnotationTest {
    public static void main(String[] args) throws Exception {
        MyService service = new MyService();

        // MyService 클래스의 메서드들 확인
        for (Method method : MyService.class.getDeclaredMethods()) {
            if (method.isAnnotationPresent(내맘대로적음.class)) {
                // 애노테이션 가져오기
                내맘대로적음 ann = method.getAnnotation(내맘대로적음.class);

                // 로그 출력
                System.out.println("[LOG] " + method.getName() + " → " + ann.value());

                // 실제 메서드 실행
                method.invoke(service);
            }
        }
    }
}

 

 

 

이렇게 코드블록들이 작동하는 것들을 확인 할 수 있다.

이제 내맘대로 @를 규정할수 있다는 매우 쓸모없는 정보를 알았다 

실무에서 활용을 언제 할 수 있는가?

 

 

몰?루?

 

 

 

진짜 왜 씀? 

멋지자너...


✅ 정리:

  • 정의되지 않은 애노테이션을 쓰면 컴파일 오류
  • 하지만 내가 @interface 로 정의해두면, 이름이 뭐든 정상적으로 사용 가능

 

Salieri
@Salieri :: 살리에리의 인생살이 채널

평소에 내가 좋아하는것과 싫어하는 것들 그리고 왜 안되나 싶은 것들을 업로드 하는 블로그입니다 인생살이도 업로드 하고있어요. 제가 걸어온 길이 당신에게 있어서 도움이 되는 이정표였으면 좋겠네요. 질문은 항상 넓은 마음으로 받고있답니다. 대답하기 곤란한 질문이 아닌 이상 제에게 이메일을 써주세요 트위터 : https://twitter.com/@Salieri1845799 깃허브 : https://github.com/salieri009

공감하셨다면 ❤️ 구독도 환영합니다! 🤗

목차