본문 바로가기
네이버클라우드/JAVA 웹 프로그래밍

JAVA 49일차 (2023-07-31) 자바 프로그래밍_주석

by prometedor 2023. 8. 1.

주석 - 일반 주석

lang.ex02

Exam100.java

package com.eomcs.lang.ex02;

//# 주석 - 일반 주석
//
//- 코드에 대한 이해를 돕기 위해 붙이는 설명이다.
//- 컴파일할 때 무시된다. 즉 .class 파일에 존재하지 않는다. 
//

/*
## 여러 줄 주석(traditional comment)
- 주석의 끝 표시를 만날 때까지 주석으로 간주된다.
- 여러 줄의 설명을 붙일 때 유용한다.
- C, C++ 프로그래밍 언어에서 사용하는 주석 문법과 같다.
*/

//## 한 줄 주석(end-of-line comment)
//- 줄이 끝날 때 까지 주석으로 간주한다.
//- C++ 프로그래밍에서 사용하는 주석 문법과 같다.


public class Exam0100 {
  public static void main(String[] args/* 이 주석은 코드 중간에 삽입할 때 유용하다.*/) {
    System.out.println("일반주석!");
  }
}

//## 실습
//1) 컴파일하기
//- $ javac -d bin/main -encoding UTF-8 src/main/java/com/eomcs/basic/ex02/Exam0100.java
//
//2) 실행하기
//- $ java -cp bin/main com.eomcs.basic.ex02.Exam0100
//

 

주석 - Javadoc 주석

lang.ex02

Exam200.java

package com.eomcs.lang.ex02;

//# 주석 - Javadoc 주석
//
//- "java document comment(doc comment)"
//- javadoc에서 HTML 문서를 만들 때 사용하는 주석이다.
//- 주로 API 문서를 자동 생성할 때 사용한다.
//- 클래스나 메서드, 변수 선언에 붙일 수 있다.
//

/**
 * 클래스에 대한 설명
 * @author eomjinyoung
 *
 */
public class Exam0200 {
  /**
   * 변수에 대한 설명
   * 변수 선언 앞에 설명을 붙여 놓으면 나중에 HTML 문서를 만들 때 추출할 수 있다.
   */
  public static String message = "Hello, world!";
  
  /**
   * 메서드에 대한 설명
   * 메서드에 대한 설명을 여기에 붙여 놓으면 나중에 HTML 문서를 만들 때 추출할 수 있다.
   * @param args 애플리테이션 아규먼트 값을 보관한 배열
   */
  public static void main(String[] args) {
    System.out.println(message);
  }
}

//## 실습
//1) Java Document 만들기
//- javadoc.exe 도구를 사용하여 자바 소스 파일에서 Javadoc 주석을 추출하여 HTML 파일을 생성해 보자.
//     javadoc 
//       -encoding [소스 파일의 문자집합]
//       -charset [생성될 HTML 파일의 문자집합]
//       -d [생성된 파일을 놓아둘 디렉토리] 
//       -sourcepath [자바 소스 경로] [자바 패키지]
//예) $ javadoc -encoding UTF-8 -charset UTF-8 -d javadoc -sourcepath src/main/java com.lang.basic.ex02
//
//2) Javadoc으로 생성한 HTML 문서 확인하기
//- /javadoc 디렉토리를 보면 자바 소스 파일에서 추출한 Javadoc 으로 만든 HTML 문서를 확인할 수 있다.
//

=>

=>

=>

=>

=>

=>

 

String.class 파일 일부

=>

ㄴ 실제 html 문서

 

주석 - 애노테이션(annotation)

lang.ex02

Exam300.java

package com.eomcs.lang.ex02;

//# 주석 - 애노테이션(annotation)
//- 클래스, 변수(필드, 아규먼트, 로컬 변수), 메서드 선언에 붙이는 주석이다.
//- 컴파일러나 JVM에서 사용할 주석이다.
//- 컴파일 한 후에도 클래스 파일(.class)에 주석을 유지할 수 있다.
//- 클래스 파일을 메모리에 로딩할 때 주석도 함께 로딩할 수 있다.
//- 실행 중에 클래스와 함께 로딩된 주석을 추출할 수 있다.
//- '프로퍼티=값' 형태로 값을 설정한다.
//
//## 애노테이션 문법
//- 작성 방법
//  @애노테이션명(프로퍼티명=값,프로퍼티명=값,...)
//  예1) @Override
//  예2) @SuppressWarnings(value="deprecation")
//  예3) @SuppressWarnings(value={"unchecked", "deprecation"})
//

public class Exam0300 {
  public static void main(String[] args) {
    System.out.println("애노테이션");
  }
  
  //## @Override 
  //- 수퍼 클래스에서 상속 받은 멤버를 재정의 한다는 것을 컴파일러에게 알린다.
  //- 컴파일러는 오버라이딩 규칙을 준수하는지 검사한다.
  //- 만약 오버라이딩 규칙을 따르지 않는다면 컴파일 오류를 발생시킬 것이다.
  //
  @Override
  public String toString() {
    return "Exam12";
  }
}

//## 실습1 : 컴파일하기
//- $ javac -d bin/main -encoding UTF-8 src/main/java/com/eomcs/basic/ex02/Exam3.java
//- 오류없이 정상적으로 컴파일 된다.
//
//## 실습2 : @Override 애노테이션의 역할을 이해하기 I
//- toString() 메서드 이름을 toString2()로 변경한 다음에 컴파일 해 보라.
//- 오버라이딩 규칙을 어겼음을 알리는 컴파일 오류가 발생한다.
//
//## 실습3 : @Override 애노테이션의 역할을 이해하기 II
//- @Override 애노테이션을 주석으로 막은 다음에 다시 컴파일 해 보라.
//- 오버라이딩 규칙을 검사하는 일을 컴파일러에게 요구하지 않는다. 
//- 컴파일러는 오버라이딩을 정상적으로 했는지 검사하지 않기 때문에 컴파일 오류가 발생하지 않는다.
//

=>

ㄴ 오버라이딩 규칙을 따르지 않으면 컴파일 오류를 발생시킴

 

애노테이션 사용

annotation.ex01

Exam0110.java

// 애노테이션 사용
package com.eomcs.annotation.ex1;


//=> 클래스, 필드, 메서드, 로컬 변수 선언에 붙이는 특별한 주석이다.
//=> 다른 주석과 달리 컴파일이나 실행할 때 추출할 수 있다.
//=> 애노테이션 문법이 도입되기 전에 
//   일반 주석에 특별한 문법을 포함시켜 사용했던 doclet 이라는 기술이 있었다.
//=> 일반 주석과 달리 '프로퍼티명=값' 형태로 값을 다룰 수 있다.
//=> 사용법
//   - 애노테이션 정의 또는 기존에 정의된 애노테이션 사용
//   - 클래스나 인터페이스에 적용
//=> .class 파일에 포함된 애노테이션을 확인하라!
//

@MyAnnotation // 클래스 선언에 붙일 수 있다.
public class Exam0110 {

  @MyAnnotation // 필드에 붙일 수 있다.
  static int a;

  @MyAnnotation int b; // 필드 선언 바로 앞에 둘 수 있다.

  @MyAnnotation // 메서드 선언에 붙일 수 있다.
  void m1(
      @MyAnnotation 
      int p1, // 파라미터(로컬변수)에 붙일 수 있다. 

      @MyAnnotation String p2
      ) {

    @MyAnnotation int local; // 로컬변수 선언에 붙일 수 있다.

    //@MyAnnotation System.out.println("okok"); // 그러나 다른 일반 문장에는 붙일 수 없다.

    //@MyAnnotation // 다른 일반 문장에는 붙일 수 없다.
    for (int i = 0; i < 100; i++) {
      @MyAnnotation int a; // 로컬 변수 선언에 붙일 수 있다.
    }
  }

  @MyAnnotation  // static, non-static 상관없이 메서드 선언에 붙일 수 있다.
  static void m2() {

  }
}

 

애노테이션 프로퍼티 사용

annotation.ex01

Exam0120.java

// 애노테이션 프로퍼티 사용
package com.eomcs.annotation.ex1;

@MyAnnotation2(value="okok")
public class Exam0120 {

  @MyAnnotation2(value="okok")
  int a;

  @MyAnnotation2(value="okok")
  void m() {}
}

 

애노테이션 유지 정책 확인

annotation.ex02

Exam0110.java

// 애노테이션 유지 정책 확인
package com.eomcs.annotation.ex2;

//애노테이션 유지 범위 
//=> CLASS
//   - .class 파일까지는 유지된다. 
//   - 그러나 runtime에는 메모리에 로딩되지 않는다.
//   - 애노테이션을 정의할 때 유지 범위를 지정하지 않으면 기본이 CLASS 이다.
//=> SOURCE
//   - 컴파일 할 때 제거된다. 
//   - .class 파일에 포함되지 않는다.
//   - 보통 소스 파일에서 애노테이션 값을 꺼내 다른 파일을 자동 생성하는 도구를 만들 때 많이 사용한다.
//=> RUNTIME
//   - .class 파일까지 유지되고, runtime에 메모리에 로딩된다.
//   - 실행 중에 애노테이션을 참조해야 할 경우에 많이 사용한다.
//

public class Exam0110 {

  public static void main(String[] args) {
    // MyClass.class 파일을 편집기로 열어서 확인해보라!

    // 클래스 정보 객체로부터 애노테이션 정보 추출
    Class<?> clazz = MyClass.class;

    // => 유지정책 : CLASS
    MyAnnotation obj = clazz.getAnnotation(MyAnnotation.class);
    if (obj == null) {
      System.out.println("MyAnnotation을 추출할 수 없습니다!");
    } else {
      // 값을 꺼낼 때는 메서드 호출하듯이 꺼내면 된다.
      System.out.println("MyAnnotation.value=" + obj.value());
    }

    // => 유지정책 : SOURCE
    MyAnnotation2 obj2 = clazz.getAnnotation(MyAnnotation2.class);
    if (obj2 == null) {
      System.out.println("MyAnnotation2를 추출할 수 없습니다!");
    } else {
      System.out.println("MyAnnotation2.value=" + obj2.value());
    }

    // => 유지정책 : RUNTIME
    MyAnnotation3 obj3 = clazz.getAnnotation(MyAnnotation3.class);
    if (obj3 == null) {
      System.out.println("MyAnnotation3를 추출할 수 없습니다!");
    } else {
      System.out.println("MyAnnotation3.value=" + obj3.value());
    }

  }
}

ㄴ 애노테이션을 정의할 때 유지 범위를 지정하지 않으면 기본이 Class 임

=>

 

애노테이션 사용

annotation.ex02

MyClass.java

// 애노테이션 사용
// => @애노테이션이름(프로퍼티명=값, 프로퍼티명=값, ...)
//
package com.eomcs.annotation.ex2;

@MyAnnotation(value="값1") // 유지정책 => CLASS 
@MyAnnotation2(value="값2") // 유지정책 => SOURCE 
@MyAnnotation3(value="값3") // 유지정책 => RUNTIME 
public class MyClass {
}

// 컴파일 한 후 .class 파일을 확인해 보라!

 

애노테이션 유지 정책 - CLASS

annotation.ex02

MyAnnotation.java

// 애노테이션 유지 정책
package com.eomcs.annotation.ex2;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

// 애노테이션의 유지 정책을 지정하지 않으면 기본이 CLASS이다.
// => 컴파일 할 때 .class 파일에 포함된다.
// => 단, 실행할 때 메모리에 로딩되지 않기 때문에 리플랙션 API로 추출할 수 없다.
@Retention(value=RetentionPolicy.CLASS)
public @interface MyAnnotation {
  String value();
}

//애노테이션 유지 범위
//1) SOURCE :  소스 파일에만 남긴다. *.class 파일에 포함 안됨. 즉 컴파일할 때 제거된다.
//2) CLASS (기본) : .class 파일에 포함. 실행할 때 로딩 안됨.
//3) RUNTIME : .class 파일에 포함. 실행할 때도 메모리에 로딩됨. 실행 시에 추출할 수 있다.

ㄴ CLASS

 

애노테이션 유지 정책 - SOURCE

annotation.ex02

MyAnnotation2.java

// 애노테이션 유지 정책
package com.eomcs.annotation.ex2;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

// 애노테이션 유지 정책을 SOURCE라고 지정하면
// => 해당 애노테이션은 컴파일할 때 제거된다.
@Retention(value=RetentionPolicy.SOURCE)
public @interface MyAnnotation2 {
  String value();
}

ㄴ SOURCE

 

애노테이션 유지 정책 - RUNTIME

annotation.ex02

MyAnnotation3.java

// 애노테이션 유지 정책
package com.eomcs.annotation.ex2;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

// 애노테이션 유지 정책을 RUNTIME라고 지정하면
// => 해당 애노테이션은 .class 파일에 포함된다.
// => 실행할 때 메모리에 로딩되기 때문에 리플랙션 API로 추출할 수 있다.
@Retention(value=RetentionPolicy.RUNTIME)
public @interface MyAnnotation3 {
  String value();
}

ㄴ RUNTIME

 

annotation.ex02

MyClass.java

클래스 파일 확인

=>

 

 

애노테이션 프로퍼티 값 지정하기

annotation.ex03

MyClass.java

// 애노테이션 프로퍼티 값 지정하기
package com.eomcs.annotation.ex3;

//@MyAnnotation // 필수 프로퍼티 값을 지정하지 않으면 컴파일 오류!
@MyAnnotation(value="값") // OK!

@MyAnnotation2 // 애노테이션의 프로퍼티 값을 지정하지 않으면 default 값이 사용된다.
//@MyAnnotation2(value="물론 이렇게 프로퍼티 값을 지정해도 된다.")

public class MyClass {
}

 

애노테이션 프로퍼티 - 선택 프로퍼티

annotation.ex03

MyAnnotation2.java

// 애노테이션 프로퍼티 - 선택 프로퍼티
package com.eomcs.annotation.ex3;

public @interface MyAnnotation2 {
  String value() default "홍길동";
  // default 값이 있으면,
  // 애노테이션을 사용할 때 값을 지정하지 않아도 된다.
}

ㄴ default 값이 있으면, 애노테이션 사용 시 값을 지정하지 않아도 됨

 

애노테이션 프로퍼티 - value 프로퍼티

annotation.ex04

MyAnnotation.java

// 애노테이션 프로퍼티 - value 프로퍼티
package com.eomcs.annotation.ex4;

public @interface MyAnnotation {
  String value(); // 필수 프로퍼티 
}

=>

애노테이션 프로퍼티 값 지정하기 - 프로퍼티 이름 생략

annotation.ex04

MyClass.java

// 애노테이션 프로퍼티 값 지정하기 - 프로퍼티 이름 생략
package com.eomcs.annotation.ex4;

//@MyAnnotation // 오류! 기본 값이 설정되어 있지 않기 때문에 반드시 프로퍼터 값을 지정해야 한다.
//@MyAnnotation(value="홍길동") // OK!
@MyAnnotation("홍길동") // OK! 'value' 라는 이름을 가진 프로퍼티는 이름 생략 가능!
public class MyClass {
}

ㄴ 'value' 라는 이름을 가진 프로퍼티는 이름 생략이 가능함

 

애노테이션 프로퍼티 - 일반 프로퍼티

annotation.ex04

MyAnnotation2.java

// 애노테이션 프로퍼티 - 일반 프로퍼티
package com.eomcs.annotation.ex4;

public @interface MyAnnotation2 {
  String tel(); // 필수 프로퍼티
}

=>

애노테이션 프로퍼티 값 지정하기 - 프로퍼티 이름 생략

annotation.ex04

MyClass2.java

// 애노테이션 프로퍼티 값 지정하기 - 프로퍼티 이름 생략
package com.eomcs.annotation.ex4;

//@MyAnnotation2 // tel 프로퍼티는 필수이다. 반드시 값을 지정해야 한다.
//@MyAnnotation2(tel = "222-2222") // OK!
//@MyAnnotation2("222-2222") // 프로퍼티 명이 'value'가 아닌 경우에는 이름 생략 불가!
public class MyClass2 {
}

ㄴ 프로퍼티가 명이 'value' 가 아니므로 tel 은 생략 불가능

 

애노테이션 프로퍼티 - 프로퍼티 생략

annotation.ex04

MyAnnotation3.java

// 애노테이션 프로퍼티 - 프로퍼티 생략
package com.eomcs.annotation.ex4;

public @interface MyAnnotation3 {
  String value(); // 필수 프로퍼티
  String tel(); // 필수 프로퍼티
}

=>

애노테이션 프로퍼티 값 지정하기 - 프로퍼티 이름 생략

annotation.ex04

MyClass3.java

// 애노테이션 프로퍼티 값 지정하기 - 프로퍼티 이름 생략
package com.eomcs.annotation.ex4;

//@MyAnnotation3 // 오류!
//@MyAnnotation3(value = "홍길동", tel = "222-2222") // OK!

//@MyAnnotation3(tel = "222-2222", value = "홍길동") // OK!
// => 프로퍼티 값을 설정할 때 순서는 상관없다.

//@MyAnnotation3("홍길동",tel="222-2222") // 오류!
// value 외 다른 프로퍼티 값도 지정할 경우,
// value 이름 생략 불가!
// value 값만 지정할 때 생략 가능!
public class MyClass3 {
}

 

ㄴ 필수 값이 value 외에 다른 프로퍼티도 존재하면 생략 불가능

ㄴ value 외 다른 프로퍼티 값도 지정할 경우에는 value 생략 불가능

 

 

애노테이션 프로퍼티 타입 - 배열

annotation.ex05

MyAnnotation2.java

// 애노테이션 프로퍼티 타입 - 배열
package com.eomcs.annotation.ex5;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation2 {
  // 배열 프로퍼티의 기본 값을 지정할 때 중괄호를 사용한다.
  String[] v1() default {"가나다","라마바"};
  int[] v2() default {100, 200, 300};
  float[] v3() default {3.14f, 4.14f, 5.14f, 6.14f};
}

ㄴ 배열 프로퍼티의 기본 값을 지정할 때는 default 와 중괄호를 사용함

=>

애노테이션 프로퍼티 타입

annotation.ex05

MyClass2.java

// 애노테이션 프로퍼티 타입
package com.eomcs.annotation.ex5;

@MyAnnotation2
public class MyClass2 {
}

ㄴ default 를 이용하여 값을 지정해두었기때문에 @MyAnnotation2 에 값을 넣어주지 않아도 오류 발생하지 않음

 

애노테이션 프로퍼티 타입 - 배열

annotation.ex05

MyAnnotation3.java

// 애노테이션 프로퍼티 타입 - 배열
package com.eomcs.annotation.ex5;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation3 {
  //  String[] v1() default {"가나다"};
  //  int[] v2() default {100};
  //  float[] v3() default {3.14f};

  // 배열 값이 한 개일 경우 중괄호를 생략할 수 있다.
  String[] v1() default "가나다";
  int[] v2() default 100;
  float[] v3() default 3.14f;
}

ㄴ 배열 값이 한 개일 경우 중괄호를 생략할 수 있음

=>

애노테이션 프로퍼티 타입

annotation.ex05

MyClass3.java

// 애노테이션 프로퍼티 타입
package com.eomcs.annotation.ex5;

@MyAnnotation3
public class MyClass3 {
}

 

애노테이션 프로퍼티 타입 - 배열 값 지정

annotation.ex05

MyClass4.java

// 애노테이션 프로퍼티 타입 - 배열 값 지정
package com.eomcs.annotation.ex5;

@MyAnnotation3(
    // 배열 값을 지정할 때 중괄호를 사용한다.
    v1 = {"홍길동", "임꺽정", "유관순"},
    v2 = {1000, 2000, 3000, 4000, 5000},
    v3 = {1.12f, 2.23f, 3, 34f})
public class MyClass4 {
}

ㄴ 배열 값을 지정할 경우 중괄호를 사용함

 

애노테이션 프로퍼티 타입 - 배열 값 지정

annotation.ex05

MyClass5.java

// 애노테이션 프로퍼티 타입 - 배열 값 지정
package com.eomcs.annotation.ex5;

@MyAnnotation3(
    //    v1={"임꺽정"},
    //    v2={1111},
    //    v3={1.11f}

    // 배열 값이 한 개일 경우 중괄호를 생략할 수 있다.
    v1="임꺽정",
    v2=1111,
    v3=1.11f
    )
public class MyClass5 {
}

ㄴ 배열 값이 한 개일 경우 중괄호를 생략할 수 있음

 

 

애노테이션 적용 범위 - 클래스나 인터페이스

annotation.ex06

MyAnnotation.java

// 애노테이션 적용 범위 - 클래스나 인터페이스
package com.eomcs.annotation.ex6;

import java.lang.annotation.ElementType;
import java.lang.annotation.Target;

// @Target을 사용하여 애노테이션을 붙일 수 있는 범위를 제어할 수 있다.
//@Target(value = {ElementType.TYPE}) // 클래스나 인터페이스 선언에만 붙일 수 있다.
// @Target(value = ElementType.TYPE) // 한 개의 값만 설정할 경우 중괄호 생략 가능!
 @Target(ElementType.TYPE) // 프로퍼티 이름이 'value'일 경우 이름 생략 가능!
public @interface MyAnnotation {
}

ㄴ @Target 을 사용하여 애노테이션을 붙일 수 있는 범위 제어 가능

ㄴ ElementType.TYPE => 클래스나 인터페이스 선언에만 붙일 수 있음

=>

애노테이션 프로퍼티 타입

annotation.ex06

MyClass.java

// 애노테이션 프로퍼티 타입
package com.eomcs.annotation.ex6;

// @MyAnnotation은 타입(인터페이스와 클래스)에만 붙일 수 있다.
@MyAnnotation // OK!
public class MyClass {

  //  @MyAnnotation
  int i; // 컴파일 오류!

  //  @MyAnnotation
  public void m(/*@MyAnnotation*/ int p) {
    /*@MyAnnotation*/ int a;
  }

}

ㄴ 필드와 메서드, 메서드의 파라미터, 로컬변수 앞에 붙일 수 없음

 

애노테이션 적용 범위 - 필드

annotation.ex06

MyAnnotation2.java

// 애노테이션 적용 범위 - 필드
package com.eomcs.annotation.ex6;

import java.lang.annotation.ElementType;
import java.lang.annotation.Target;

@Target(ElementType.FIELD)
public @interface MyAnnotation2 {
}

ㄴ ElementType.FIELD => 필드에만 붙일 수 있음

=>

애노테이션 프로퍼티 타입

annotation.ex06

MyClass2.java

// 애노테이션 프로퍼티 타입
package com.eomcs.annotation.ex6;

// @MyAnnotation2은 필드에만 붙일 수 있다.
//@MyAnnotation2
public class MyClass2 {

  @MyAnnotation2 int i;
  @MyAnnotation2 static int i2;


  //  @MyAnnotation2
  public void m(/*@MyAnnotation2*/ int p) {
    /*@MyAnnotation2*/ int a;
  }

}

ㄴ 클래스와  메서드, 메서드의 파라미터, 로컬변수 앞에 붙일 수 없음

 

애노테이션 적용 범위 - 메서드

annotation.ex06

MyAnnotation3.java

// 애노테이션 적용 범위 - 메서드
package com.eomcs.annotation.ex6;

import java.lang.annotation.ElementType;
import java.lang.annotation.Target;

@Target(ElementType.METHOD)
public @interface MyAnnotation3 {
}​

ㄴ ElementType.METHOD => 메서드에만 붙일 수 있음

=>

애노테이션 프로퍼티 타입

annotation.ex06

MyClass3.java

// 애노테이션 프로퍼티 타입
package com.eomcs.annotation.ex6;

// @MyAnnotation3는 메서드에만 붙일 수 있다.
//@MyAnnotation3
public class MyClass3 {

  /*@MyAnnotation3*/ int i;
  /*@MyAnnotation3*/ static int i2;


  @MyAnnotation3
  public void m(/*@MyAnnotation3*/ int p) {
    /*@MyAnnotation3*/ int a;
  }

}

ㄴ 클래스와  필드, 메서드의 파라미터, 로컬변수 앞에 붙일 수 없음

 

애노테이션 적용 범위 - 로컬 변수

annotation.ex06

MyAnnotation4.java

// 애노테이션 적용 범위 - 로컬 변수
package com.eomcs.annotation.ex6;

import java.lang.annotation.ElementType;
import java.lang.annotation.Target;

@Target(ElementType.LOCAL_VARIABLE)
public @interface MyAnnotation4 {
}

ㄴ ElementType.LOCAL_VARIABLE => 로컬변수에만 붙일 수 있음

=>

애노테이션 프로퍼티 타입

annotation.ex06

MyClass4.java

// 애노테이션 프로퍼티 타입
package com.eomcs.annotation.ex6;

// @MyAnnotation4는 로컬 변수에만 붙일 수 있다.
//@MyAnnotation4
public class MyClass4 {

  /*@MyAnnotation4*/ int i;
  /*@MyAnnotation4*/ static int i2;


  //@MyAnnotation4
  public void m(/*@MyAnnotation4*/ int p) {
    @MyAnnotation4 int a;
  }

}

ㄴ 클래스와  필드, 메서드, 메서드의 파라미터 앞에 붙일 수 없음

 

애노테이션 적용 범위 - 로컬 변수 + 파라미터 + 필드

annotation.ex06

MyAnnotation5.java

// 애노테이션 적용 범위 - 로컬 변수 + 파라미터 + 필드
package com.eomcs.annotation.ex6;

import java.lang.annotation.ElementType;
import java.lang.annotation.Target;

@Target({ElementType.LOCAL_VARIABLE, ElementType.PARAMETER, ElementType.FIELD})
public @interface MyAnnotation5 {
}

ㄴ동시에 여러 개 설정 가능

    ㄴ ElementType.LOCAL_VARIABLE => 로컬변수에 붙일 수 있음

    ㄴ ElementType.PARAMETER => 파라미터에 붙일 수 있음

    ㄴ ElementType.FIELD => 필드에 붙일 수 있음

=>

애노테이션 프로퍼티 타입

annotation.ex06

MyClass5.java

// 애노테이션 프로퍼티 타입
package com.eomcs.annotation.ex6;

// @MyAnnotation5는 로컬 변수, 파라미터, 필드에만 붙일 수 있다.
//@MyAnnotation5
public class MyClass5 {

  @MyAnnotation5 int i;
  @MyAnnotation5 static int i2;


  //@MyAnnotation5
  public void m(@MyAnnotation5 int p) {
    @MyAnnotation5 int a;
  }

}

ㄴ 클래스와 인터페이스, 메서드를 제외한 필드, 메서드의 파라미터, 로컬변수에 붙일 수 있음

 

 

애노테이션 중복 사용

annotation.ex07

MyClass.java

// 애노테이션 중복 사용
package com.eomcs.annotation.ex7;

@Company("비트캠프")
//@Company("비트캠프") // 중복 사용 불가!
public class MyClass {

  @Company("비트캠프")
  //@Company("비트캠프") // 중복 사용 불가!
  public void m1(int p) {}

  @Company("비트캠프")
  //@Company("비트캠프") // 중복 사용 불가!
  public void m2(int p) {}
}

 

애노테이션 중복 사용 - 여러 번 사용 가능

annotation.ex07

Employee.java

// 애노테이션 중복 사용 - 여러 번 사용 가능
package com.eomcs.annotation.ex7;

import java.lang.annotation.Repeatable;

// 애노테이션을 중복해서 사용할 수 있게 하려면
// - @Repeatable 로 표시해 줘야 한다.
// - 이때 반복에 대한 정보를 따로 정의한 애노테이션을 지정해야 한다.
@Repeatable(value=Employees.class)
public @interface Employee {
  String value();
}

ㄴ Employees 클래스에 대해 @Repeatable 애노테이션을 적용

=>

애노테이션 중복 사용 - 중복해서 사용할 애노테이션을 지정한다.

annotation.ex07

Employees.java

// 애노테이션 중복 사용 - 중복해서 사용할 애노테이션을 지정한다.
package com.eomcs.annotation.ex7;

public @interface Employees {
  Employee[] value();
}

ㄴ 중복해서 사용할 애노테이션을 지정함 (Employee)

=>

애노테이션 중복 사용

annotation.ex07

MyClass2.java

// 애노테이션 중복 사용
package com.eomcs.annotation.ex7;

// @Employees 애노테이션에 @Employee 반복을 정의하였다.
// 그리고 @Employee 애노테이션에 반복할 수 있음을 선언하였다.
// 따라서 다음과 같이 중복 선언할 수 있다.
//
@Employee("홍길동")
@Employee("임꺽정")
public class MyClass2 {

  @Employee("홍길동")
  @Employee("임꺽정")
  public void m1(int p) {}

  @Employee("홍길동")
  @Employee("임꺽정")
  public void m2(int p) {}
}

ㄴ @Emplyees 애노테이션에 @Employee 반복을 정의한 후 @Employee 애노테이션에 반복할 수 있도록 하는 @Repeatable 애노테이션을 선언하였으므로 위와 같이 중복 선언 가능함