안드로이드 공부를 하다보니 어노테이션이 등장했다.
이 글에선 어노테이션이 어떤 역할을 하는지에 대해서 정리해보려고 한다.
1. 어노테이션은 뭘까?
안드로이드 프로그램을 만들 때 @가 붙어있는 것들이 보일 것이다.
@Override, @Singleton, @NonNull, @Stringres, @Colorres 등등
이와 같은 것들을 어노테이션이라고 한다.
2. 왜 쓰는 걸까?
첫번째 이유 : 컴파일 단계에서 유효한 리소스를 받아왔는지 확인하기 위해서이다.
위의 화면을 보면 Question 클래스에 @StringRes라는 어노테이션을 사용했다.
이 과정을 통해서 string resource에 지정되어 있지 않은 Id가 들어오면 컴파일러가 오류를 표시할 것이다.
string resource가 지정되어 있는 strings.xml이다.
@StringRes 어노테이션은 여기에 지정되어 있는 string만 받아올 것이다.
두번째 이유 : 다른 개발자가 보기에 편하다.
어떤 타입의 인자가 들어오는지 바로 확인할 수 있고, 어떤 리소스가 들어오는지에 대한 범위가 정해져있다보니 만약 문제가 생겼을 때도 확인해야하는 범위가 확실히 줄어든다.
3. 어떤 방식으로 동작할까?
1. 컴파일 수행
2. 실행되지 않은 어노테이션 프로세서 수행
3. 어노테이션이 달린 리소스들 처리
4. 컴파일러가 모든 어노테이션 프로세서의 실행을 확인
4. 어노테이션의 종류는 어떤 것들이 있을까?
@NonNull, @Nullable
null의 허용여부를 정하는 어노테이션
@StringRes, @DrawableRes, @ColorRes
리소스는 모두 각자의 Id를 가지고 있고 위의 어노테이션은 그 리소스들의 Id를 인자로 받아와서 리소스에 지정되어 있는지 확인한다.
@ColorInt, @ColorRes
ColorInt는 인자로 ARGB값을 받고, Res는 Id를 인자로 받는다.
@Dimension, @Px
dp, sp인지 px인지 명시한다. @Dimension(unit = Dimension.SP) 와같은 방식으로 사용한다.
@IntRange, @FloatRange
숫자형 값의 범위를 한정할 수 있다. ex) @FloatRange(from=0.0, to=1.0)
@Size
배열, 컬렉션 크기 그리고 문자열 길이를 한정한다.
@Size(multiple=n) : n의 배수로 한정
@Size(min=5, max= 12)
@IntDef, @StringDef
int, String으로 이루어진 프리미티브 타입을 Enum처럼 안전하게 쓸 수 있도록 제약한다.
@UiThread, @MainThread, @WorkerThread, @BindThread
명시한 스레드에서만 메서드를 호출할 수 있도록 함. Ui와 Main스레드는 실질적으로 동일하다.
@CallSuper
하위 클래스에서 오버라이드할 때 반드시 상위 클래스의 메서드를 호출하도록 강제
@CheckResult
반드시 메서드 반환값을 사용하도록 강제 (조건 만족 여부 를 boolean 타입으로 반환할 때)
@RequiresPermission
이 애너테이션이 붙은 메서드나 인텐트 액션, 콘텐츠 프로바이더를 사용할 때 필요한 권한을 나타낸다. 이 권한이 AndroidManifest.xml에 설정되어 있지 않으면 오류가 발생
@RequiresApi
Support Annotation 라이브러리 24.0.0에 추가되었고 필요한 최소 API 레벨을 나타낸다. @TargetApi와 유사하지만 더 명확히 표현하는 것이 목적이다. minSdkVersion 값이 명시된 API 레벨보다 낮으면 오류가 발생한다.
@Keep
소스 코드 최적화시 제거 또는 이름 변경이 안 됨을 나타낸다. ProGuard로 소스 코드 최적화시 리플렉션으로 접근해야 하는 요소는 -keep 규칙을 지정해야 한다. @Keep 애너테이션으로 최적화하지 않게 지정할 수 있는데 자동으로 최적화 대상에서 제외되지는 않아서 ProGuard 설정을 추가해야 한다.
@VisibleForTesting
테스트 코드는 대상 클래스의 private 메서드에 접근할 수 없는데 1. 테스트 클래스에서 접근할 수 있게 가시성을 완화하거나 2. 리플렉션을 이용하거나 3. 테스트하지 않는다.
1번은 캡슐화 원칙을 위반한다. @VisibleForTesting은 1번을 대체하는 애너테이션이다.
5. 어노테이션을 만들 수는 없을까?
물론 직접 원하는 어노테이션을 만들 수 있다.
어떻게 만드는 지에 대해서는 아래 링크의 블로그에서 상세히 설명을 해주셨으니 블로그를 소개하는 것으로 마무리를 짓겠다.
[Android] Annotation Processor 만들기 | 찰스의 안드로이드
[Android] Annotation Processor 만들기 | 찰스의 안드로이드
Annotation이란 ? 애노테이션이란 무엇일까요? 사실 우리 모두가 이미 정의된 애노테이션을 쓰고 있습니다. 예를 들면, @Override 어노테이션을 사용하여 메소드를 재정의하고 싱글톤 패턴을 사용하
www.charlezz.com