JAVA 사용자 정의 메모 및 반사를 통한 메모 매개변수 분석
6236 단어 사용자 정의 메모
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의 사용자 정의 주해의 작은 예입니다. 깊이 있게 연구하고 있습니다. 먼저 들어가서 이야기합시다. 허허......