IT_Programming/Java

[펌] Annotation (주석)

JJun ™ 2008. 8. 28. 09:44

Annotation(주석)

1. Annotation(주석) 개요

J2SE 5.0에 추가된 중요한 기능중 하나로, 어노테이션 유형은 일반 클래스와 비슷해보이지만 독특한 속성이 있다.
표기법은 (@)(at) 표시로 하고, 클래스에서 @(at)기호와 함께 사용하여 다른 자바 코드에 주석을 달 수 있다.
주석태그가 코멘트가 아니라 소스에 포함된다. 여기서 중요한 점은 주석이 선언적 프로그래밍 모델을 체계적으로 지원하기 위한 방법이라는 것이다.

1.1. 주석이란

  • 메타데이터를 프로그램 엘리먼트(클래스, 인터페이스, 메소드 등)에 연결하는 방법을 제시합니다.
    (메타데이터는 데이터를 부연설명하기 위한 데이터)
  • 주석은 해당 엘리먼트에 대해 생성된 바이트코드를 변경하지 않는 추가 수식자(modifier)라고 할 수 있다.

1.2. 주석의 지속성

 

 

  • //, /* */, /** */ 등의 주석은 보통 컴파일이 되면서 사라진다.
  • Annotation은 기존의 주석과 달리 Runtime 까지도 존재하는 주석이다.

2. Builtln(내장된) Annotation(주석)

  • 모든 자바 프로그래머들이 알아야 하는 내장 어노테이션은 @Deprecated, @Override, @SuppressWarnings 모두 3가지 이다.

2.1. Override Annotation

  • Tiger의 첫 번째 Builtln(내장된) Annotation 유형이다.
  • @Override는 메소드에 대해서만 사용되어야 한다. (클래스, 패키지 선언, 기타 구조체는 안된다.)
  • @Override 주석이 사용된 메서드는 수퍼클래스에서 메소드를 오버라이드한다는 것을 나타낸다.

2.1.1. @Override 예제

The Override Annotation

package dfi.study.java;
public class OverrideTest01{
  public OverrideTest01() { }
  @Override
  public String toString() {
    return super.toString() + " [Override Test]";
  }
  @Override
  public int hasCode() {
    return toString().hashCode();
  }
}
  • 위의 @Override 어노테이션은 두 개의 메소드, toString()과 hashCode()가 OverrideTest01 클래스의 수퍼클래스 (java.lang.Object)에서
    메소드의 버전을 오버라이드 한다는 것을 나타내고 있다.
  • 메소드를 오버라이드 하려다가 메소드 이름의 철자를 틀리거나, 잘못된 인자를 지정하거나, 다른 리턴 타입을 설정했던 적이 무수히 많았을 것이다.
    이 어노테이션 유형은 코딩하기엔 너무 늦었거나 무언가를 잘못 타이핑했을 때 빛을 발한다.

Override Annotation의 오타 찾아내기

 

 

  • 위 코드에서 hashCode()가 hasCode()로 잘못 표기되었다. @Override 어노테이션은 hasCode()가 메소드를 오버라이드해야 한다는 것을 지시한다.
    하지만 컴파일시 오버라이드 할 hasCode()라는 메소드가 없다는 것을 알게 되고. 결과적으로 컴파일러는 에러를 표시한다.

2.2. Deprecated Annotation

  • @Override와 마찬가지로 @Deprecated는 marker 어노테이션이다.
  • @Deprecated를 사용하여 더 이상 사용되지 말아야 하는 메소드에 주석을 단다. 주의할 점은 더 이상 사용되지 말아야 하는(depreciated) 메소드와
    같은 라인상에 놓여져야 한다는 것이다.
  • 컴파일러는 프로그램이 비추천(deprecated) 메소드나 클래스 혹은 변수를 사용할 때마다 경고를 발생시킨다.
  • 메소드에 @Deprecated 태그를 플래그하면 해당 메소드나 클래스 사용시 사용자에게 경고 메세지를 보내도록 컴파일러를 환기시키는 효과가 있다.
  • 태그는 소문자 'd'로 시작하며, Annotation은 대문자' D'로 시작함을 유의해야한다.
  • 일반적으로 프로그래머는 비추천 메소드의 사용을 피해야 하며 그것 대신 무엇을 사용해야 하는지를 확인해야 한다.

2.2.1. @Deprecated 예제

The Deprecated Annotation

 

 

  • 주석이 붙은 클래스도 주석이 붙지 않은 경우와 동일한 방식으로 컴파일한다.
  • 이 클래스를 컴파일 할 때 비정상적인 그 어떤 것도 기대해서는 안된다.
     
  •  
  • 오버라이드 또는 호출이든 @Depreciated 메소드를 사용하면 컴파일러는 어노테이션을 처리하고
    메소드가 사용되어서는 안된다는 것을 알게 되고 에러 메시지를 만든다.

2.3. SuppressWarnings Annotation

  • 마지막 어노테이션 유형은 SuppressWarnings으로 가장 흥미롭다고 할 수 있다.
  • @SuppressWarnings은 일반적으로 경고하는 내용을 경고하지 말도록 컴파일러에게 지시하는데, 경고는 일종의 범주에 속하므로 주석에 대해
    어떤 종류의 경고를 금지할 것인지 지시해야 한다.
  • Override와 Deprecated와는 다르게 SupressWarnings는 변수를 갖고 있다. 따라서 이를 작동하게 하려면 싱글-어노테이션 유형을 사용해야한다.
  • javac 컴파일러는 all, deprecation, unchecked, fallthrough, path, serial, finally 등 7개의 금지 옵션을 정의한다.
  • 언어 스펙은 이 중에서 두 가지 비추천(deprecation)"과 "비확인(unchecked) 만을 정의한다.
  • 하나 이상의 경고 종류를 억제하려면 다음의 문법과 같이 사용하면 된다.
    @SuppressWarnings({"unchecked", "deprecation"})

2.3.1. @SuppressWarnings 예제

The SuppressWarnings Annotation (type-safe가 아닌 Tiger 코드)

package dfi.study.java;
import java.util.ArrayList;
public class SuppressWarningsTest01
{
  public void SuppressWarningsTest01()
  {
    ArrayList wordList = new ArrayList();    // no typing information on the List
	
    wordList.add("study");                // causes error on list addition
  }
}

non-typed 코드에서 컴파일러 경고

 

 

-컴파일 라인에 -Xlint를 추가하면 무엇이 잘못되었는지 구체적으로 표시할 수 있다.

 

경고 제거하기

  • SuppressWarnings 어노테이션을 사용하여 번거로운 경고를 제거한다
    -@SuppressWarnings(value={"unchecked"})를 적용함.
package dfi.study.java;
import java.util.ArrayList;
@SuppressWarnings(value={"unchecked"})
public class SuppressWarningsTest01
{
  public void SuppressWarningsTest01()
  {
    ArrayList wordList = new ArrayList();    // no typing information on the List
	
    wordList.add("study");                // causes error on list addition
  }
}


 

어노테이션 문법 자체가 자바스크립트와 상당히 비슷하네요.
특히 <Listing 1. 어노테이션에서 어레이 값 사용하기> 이부분 문법은 js에서 연관배열인 JSON 스타일로 구현된
방법과 너무 나도 비슷 하네요.
ex)

var Sport = {
   basketBall :  '농구',
   soccer : '축구',
   playSport : function() {
     alert('gogo');
   },
   stopSport : function() {
     alert('stop');
   } 
 }
@TODOItems({    // Curly braces indicate an array of values is being supplied
  @TODO(
    severity=TODO.CRITICAL,
    item="Add functionality to calculate the mean of the student's grades",
    assignedTo="Brett McLaughlin"
  ),
  @TODO(
    severity=TODO.IMPOTANT,
    item="Print usage message to screen if no command-line flags specified",
    assignedTo="Brett McLaughlin"
  ),
  @TODO(
    severity=TODO.LOW,
    item="Roll a new website page with this class's new features",
    assignedTo="Jason Hunter"
  )
})