JAVA 사용자 정의 메모 및 반사를 통한 메모 매개변수 분석


1. 개념:
 
주해는 JDK5가 도입한 새로운 특성으로 처음에 코드 주석에서 파생되었지만 지금은 이미 주석의 범주를 넘어섰기 때문에 나는 두려워서 주석이라는 어휘로 그를 묘사할 수 없다. 비록 기존의 많은 자료에서 여전히 주석이라고 부른다.반사로 인해 많은 기술의 실현(동적 대리, 의존 주입 등)에 기초가 생겼다면 주해는 이러한 기술의 실현을 평민화시키는 기초이다.
 
class 파일 규범에서 알 수 있듯이 JDK5에서부터 class 파일은 주석 설명 세션을 도입했다.자바 가상기의 측면에서 볼 때class가 보류하고 실행할 때 보류하는 주석은 자바 바이너리 코드와 동등한 위치에 있다.가상 컴퓨터는class 파일을 불러올 때 주석 내용에 공간을 분배하고 해석하며 최종적으로 주석과 대응하는 이진 코드에 관련을 맺는다.비록 이 주석들은 실행되지 않지만, 코드에 대한 설명 능력은 반사 기술과 결합하면 우리가 너무 많은 일을 할 수 있다.
 
자바는 내장된 주석 (@Override, @Deprecated 등) 을 제외하고 사용자 정의 주석 (Struts, Hibernate 등 많은 프레임워크, 심지어 자바 자체도 많은 사용자 정의 주석을 실현하고 있음을 알고 있습니다.물론 더 대단한 것은 원주해다. 원주해는 주해를 묘사하는 주해이다.
 
사용자 정의 주석을 실현하려면 @interface 키워드를 통해 정의해야 합니다.또한 @interface 이전에 메타 주석을 통해 이 주석의 사용 범위 (@Target), 생명주기 (@Retention) 및 기타 (기타 중요하지 않음) 를 설명해야 한다.
 
@Target는 메모의 사용 범위를 설명하는 데 사용됩니다. 즉, 메모가 사용될 수 있는 위치는 다음과 같습니다.
값을 얻다
묘사
CONSTRUCTOR
구조자 설명
FIELD
도메인 설명
LOCAL_VARIABLE
로컬 변수를 설명하는 데 사용
METHOD
설명 방법
PACKAGE
설명 패키지
PARAMETER
매개변수 설명에 사용
TYPE
클래스나 인터페이스를 설명하는 데 사용 (심지어 enum)
 
@Retention 은 다음과 같은 메모의 라이프 사이클을 설명하는 데 사용됩니다.
값을 얻다
묘사
SOURCE
소스 파일에 유효
CLASS
class 파일에 유효
RUNTIME
런타임 시 유효(런타임 시 일반)
 
다음은 바로 예를 살펴보겠습니다.
먼저 여러 가지 다른 유형의 주석 방식을 정의한다
1. 클래스에 작용하는
 
@Target(ElementType.TYPE)//        
@Retention(RetentionPolicy.RUNTIME)
public @interface MyClassAnnotation {
	 String uri();  
	 String desc(); 
}

2, 필드 위의
 
 
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyFieldAnnotation {
	 String uri();  
	 String desc(); 
}

3. 구조에 작용하는
 
 
@Target(ElementType.CONSTRUCTOR)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyConstructorAnnotation {
	 String uri();  
	 String desc(); 
}

4, 방법 위에 작용
 
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyMethodAnnotation {
	 String uri();  
	 String desc(); 
}

 
 
실례를 통해서 어떻게 사용하는지...
public class MyAllAnnotationTest {
	
	@SuppressWarnings("unchecked")
	public static void main(String[] args) {
		
		MySample sample = new MySample();
		Class clazz = sample.getClass();
		// 
		boolean c = clazz.isAnnotationPresent(MyClassAnnotation.class);
		if (c) {
			MyClassAnnotation myClassAnnotation = (MyClassAnnotation) clazz.getAnnotation(MyClassAnnotation.class);
			printMyClassAnnotation(myClassAnnotation);
		}
		
		//  
		Constructor[] constructors = clazz.getConstructors();
		for (Constructor constructor : constructors) {
			boolean cc = constructor.isAnnotationPresent(MyConstructorAnnotation.class);
			if (cc) {
				MyConstructorAnnotation myConstructorAnnotation = (MyConstructorAnnotation) constructor.getAnnotation(MyConstructorAnnotation.class);
				printMyConstructorAnnotation(myConstructorAnnotation);
			}
		}
		
		//  
		Field[]  fields = clazz.getDeclaredFields();
		for (Field field : fields) {
			boolean f = field.isAnnotationPresent(MyFieldAnnotation.class);
			if (f) {
				MyFieldAnnotation myFieldAnnotation = (MyFieldAnnotation)field.getAnnotation(MyFieldAnnotation.class);
				printMyFieldAnnotation(myFieldAnnotation);
			}
		}
		
		//  
		Method[] methods = clazz.getDeclaredMethods();
		for (Method method : methods) {
			boolean m = method.isAnnotationPresent(MyMethodAnnotation.class);
			if (m) {
				MyMethodAnnotation methodAnnotation = (MyMethodAnnotation)method.getAnnotation(MyMethodAnnotation.class);
				printMyMethodAnnotation(methodAnnotation);
			}
		}
	}
	
	
	public static void printMyClassAnnotation(MyClassAnnotation myClassAnnotation){
		if (null == myClassAnnotation) {
			return;
		}
		System.out.println("url = " + myClassAnnotation.url());
		System.out.println("desc = " + myClassAnnotation.desc());
		
	}
	public static void printMyConstructorAnnotation(MyConstructorAnnotation myConstructorAnnotation){
		if (null == myConstructorAnnotation) {
			return;
		}
		System.out.println("url = " + myConstructorAnnotation.url());
		System.out.println("desc = " + myConstructorAnnotation.desc());
	}
	public static void printMyFieldAnnotation(MyFieldAnnotation myFieldAnnotation){
		if (null == myFieldAnnotation) {
			return;
		}
		System.out.println("url = " + myFieldAnnotation.url());
		System.out.println("desc = " + myFieldAnnotation.desc());
	}
	
	
	public static void printMyMethodAnnotation(MyMethodAnnotation methodAnnotation){
		if (null == methodAnnotation) {
			return;
		}
		System.out.println("url = " + methodAnnotation.url());
}
 
 
인쇄 결과는 다음과 같습니다.
 
url = cn.cd.sg.test.reflect.MySample
desc = The Class Name For MySample
url = cn.cd.sg.test.reflect.MySample#MySample For Constructor
desc = The default constuctor Name For MySample()
url = cn.cd.sg.test.reflect.MySample#id
desc = The Field Name For Id
url = cn.cd.sg.test.reflect.MySample#name
desc = The Field Name For Name
url = cn.cd.sg.test.reflect.MySample#setId
desc = The Mrthod Name For setId()
url = cn.cd.sg.test.reflect.MySample#getName
desc = The Mrthod Name For getName()
url = cn.cd.sg.test.reflect.MySample#getId
desc = The Mrthod Name For getId()
url = com.sg.annotation.MySample#setName
desc = The Mrthod Name For setName()
 
 
 
이상은 바로 JAVA의 사용자 정의 주해의 작은 예입니다. 깊이 있게 연구하고 있습니다. 먼저 들어가서 이야기합시다. 허허......
 

좋은 웹페이지 즐겨찾기