21. 자바 반사 메커니즘 과 주해

반사, reflection, 그 이름 을 들 으 면 거울 을 보 는 것 처럼 자신 도 볼 수 있 고 다른 사람 도 볼 수 있다.자바 언어 에서 이것 은 매우 중요 한 특성 이다.다음은 sun 회사 홈 페이지 에서 반사 에 대한 소개 입 니 다.
Reflection is a feature in the Java programming language. It allows an executing Java program to examine or "introspect(  )" upon itself, and manipulate(  ) internal properties of the program. For example, it's possible for a Java class to obtain the names of all its members and display them.
The ability to examine and manipulate a Java class from within itself may not sound like very much, but in other programming languages this feature simply doesn't exist. For example, there is no way in a Pascal, C, or C++ program to obtain information about the functions defined within that program.
One tangible(   ) use of reflection is in JavaBeans, where software components can be manipulated visually via(  ) a builder tool. The tool uses reflection to obtain the properties of Java components (classes) as they are dynamically loaded.
   java       ,        (         )                   。       java                     。               java       ,        C  C++            。 Pascal、C、C++             ;        JavaBean ,          javaBean     ,               javaBean            。

 반사 메커니즘 을 이해 하려 면 반드시 java. lang. Class 에 대해 알 아야 한다. 18, 19 장 참조.
먼저 Class 의 구조 기 를 보십시오.
    /*
     * Constructor. Only the Java Virtual Machine creates Class
     */
    private Class() {}

 주석 은 이 종 류 는 JVM 이 만 들 어 졌 기 때문에 귀 찮 게 하지 않 아 도 된다 는 것 을 명확 하 게 알려 주 었 다.만약 우리 가 하나의 유형의 정 보 를 얻 게 된다 면 반 사 를 이용 하여 각종 구성원 과 방법 을 얻 을 수 있 을 것 이다.(비고: Class 는 JDK 1.5 버 전부터 팬 서 비 스 를 더 많이 받 았 습 니 다) 그러면 우 리 는 어떻게 한 가지 유형의 정 보 를 얻 을 수 있 습 니까?만약 에 우리 에 게 Role 류 가 있다 고 가정 하면:
package org.Smart;
   /*
    * a class Role has some methods and attribute
    */
public class Role {
    public Role(){}
    public Role(String s){}
    private String s;
    private int x;
    public void fun1(String s){
    System.out.println(s);
    }
    public  void  fun2(){
    	System.out.println("ok");
    }
}

 테스트:
public class Sample { 
    @SuppressWarnings("rawtypes")
	public static void main(String...s)  {
    	Class c=Role.class;
    	Method[] m=c.getDeclaredMethods();
    	for(int x=0;x<m.length;x++){
    		System.out.println(m.toString());
    	}
    }
 }

 
Class 인 스 턴 스 를 가 져 오 는 몇 가지 방법:
Class cls1 = Role.class;
Class cls2 = Class.forName("org.Smart.Role");
Role r=new Role();
Class cls3=r.getClass();
Class cls4= Boolean.TYPE;  //            

두 번 째 방식 에서 forName 의 인 자 는 반드시 완전한 클래스 (패키지 이름 + 클래스 이름) 이 고 이 방법 은 이상 을 포착 해 야 합 니 다.이제 cls 1 을 얻 으 면 Role 클래스 의 인 스 턴 스 를 만 들 수 있 습 니 다. Class 의 new Instance 방법 을 이용 하여 호출 클래스 의 기본 구조 기 에 해당 합 니 다.
Class c;
try {
     c = Class.forName("org.Smart.Role");
     Role r=(Role) c.newInstance();        //  Role r=new Role();  newInstance()   Role       
     r.fun2();
} catch (ClassNotFoundException e) {
     e.printStackTrace();
}

구조 기 획득: getConstructors / getDeclared Constructors (사유 / 사유 포함 하지 않 음) 사유 또는 공유 로 설정 할 수 있 습 니 다.
획득 속성: getFields / getDeclaredFields
획득 방법: getMethods / getDeclaredMethods
 
클래스 호출 방법:
Class c= Role.class;
    	Object obj=c.newInstance();
    	Method fun=c.getDeclaredMethod("fun1", String.class); //   fun1     null,         
    	fun.invoke(obj, "e");//     null,       

속성 값 설정:
Field f=c.getDeclaredField("x");
f.setInt(obj, 32); //int x;   public   ,setInt int   ;

여기까지 자바. lang. reflect 패키지 의 Method / Field / constructor 류 를 사 용 했 습 니 다. 이 종 류 는 모두 Class. get () 을 받 아 얻 은 방법 / 속성 / 구조 기 이 고 가장 중요 한 운용 도 있 습 니 다. jvm 핵심 중 하나 인 Proxy 대 리 는 다음 장 내용 에서 설명 할 것 입 니 다.
Class 의 기타 중요 한 방법:
static Class<?>	              forName(String name, boolean initialize, ClassLoader loader) //Class    
static Class<?>	              forName(String className)//      
<A extends Annotation>A       getAnnotation(Class<A> annotationClass)
Annotation[]	              getAnnotations()
ClassLoader	              getClassLoader()//      
Class<?>[]	              getInterfaces() //    
String	                      getName()//    
Package   	              getPackage()  //     
Class<? super T>	      getSuperclass()//    

 
다음은 이어서 주 해 를 말씀 드 리 겠 습 니 다.
JDK 5 에는 소스 코드 의 주석 (annotation) 이라는 메커니즘 이 도입 됐다.주 해 는 자바 소스 코드 에 기능 적 인 실현 코드 를 포함 할 수 있 을 뿐만 아니 라 메타 데이터 도 추가 할 수 있 게 한다.주해 의 기능 은 코드 중의 주석 과 유사 하 며, 다른 것 은 주해 가 코드 기능 을 제공 하 는 설명 이 아니 라 프로그램 기능 을 실현 하 는 중요 한 구성 부분 이다.자바 주 해 는 이미 많은 프레임 워 크 에서 광범 위 하 게 사용 되 어 프로그램의 설정 을 간소화 하 는 데 사용 되 었 다.
 
자바 주 해 는 자바 레이 블 이 라 고도 부 릅 니 다. 자바 는 방법, 클래스, 파라미터, 가방, 도 메 인 및 변수 등에 대해 표준 을 추가 할 수 있 는 메커니즘 을 제공 합 니 다 (즉, 일부 정 보 를 첨부 합 니 다).또한 앞으로 어느 시간 대 에 반 사 를 통 해 표 시 된 정 보 를 추출 하여 사용 할 수 있 도록 한다.
자 바 는 1.5 버 전 이후 기본적으로 세 개의 레이 블 을 내장 합 니 다. 
@ Override: 방법 위 에 만 사용 할 수 있 습 니 다. 다른 사람 에 게 이 방법 은 부 류 를 바 꾸 는 것 입 니 다. 
@ Deprecated: 오래된 API 를 사용 하지 말 것 을 권장 합 니 다. 컴 파일 할 때 경고 메 시 지 를 사용 합 니 다. 프로그램의 모든 요소 에 설정 할 수 있 습 니 다. 
@ Suppress Warnings: 이 유형 은 경고 메 시 지 를 잠시 닫 을 수 있 습 니 다. 
그러나 이 세 가지 표시 만 으로 는 우리 가 개발 할 때의 수 요 를 만족 시 킬 수 없다.그래서 자바 에 서 는 사용자 정의 주 해 를 사용 할 수 있 습 니 다.
 
어떤 측면 에서 볼 때 주 해 를 XML 요소 로 볼 수 있 고 이 요 소 는 서로 다른 미리 정 의 된 속성 을 가 질 수 있다.속성의 값 은 이 요 소 를 설명 할 때 스스로 지정 할 수 있 습 니 다.코드 에 주 해 를 사용 하면 일부 메타 데 이 터 를 XML 파일 에서 코드 자체 로 옮 겨 한 곳 에서 관리 하고 유지 하 는 것 과 같 습 니 다.
 
어떻게 스스로 주 해 를 설계 합 니까?
먼저 rt. jar 아래 자바. lang. annotation 가방 을 보 세 요.
Target.class
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Target {        //@Target          ,    ANNOTATION_TYPE  
    ElementType[] value();
}
  //Java         ,           ,    
  //@Documented      JavaDoc 32  public @interface Documented {
  //@Inheried                 
  //@Retention   ,        。   RetentionPoicy    :public @interface Retention{   
  //RetentionPolicy.SOURCE:    java   ,        public enum RetentionPolicy {
  //RetentionPolicy.CLASS:   class   ,   VM  (  )
  //RetentionPolicy.RUNTIME:       ,VM          ,                 

  //@Target   ,         。   ElementType        
  //ElementType.CONSTRUCTOR:         public enum ElementType {
  //ElementType.FIELD:     、  、  (  enum  )
  //ElementType.LOCAL_VARIABLE:       
  //ElementType.METHOD:     
  //ElementType.PACKAGE:    
  //ElementType.PARAMETER:     
  //ElementType.TYPE:  、  (      ) enum         
   //ElementType.ANNOTATION_TYPE  Annotation type declaration

   @interface 는 하나의 키워드 입 니 다. 주 해 를 디자인 할 때 하나의 유형 을 @ interface 로 정의 해 야 합 니 다. class 나 interface 키 워드 를 사용 할 수 없습니다. @ Retention 은 주 해 를 설명 하 는 보존 정책 입 니 다. CLASS, RUNTIME, SOURCE 등 세 가지 속성 이 있 습 니 다. 주 해 는 바이트 코드. class 파일, JVM 실행 시간 과 소스 코드. 자바 파일 에 저 장 됩 니 다.런 타임 이 라 고 밝 혀 졌 을 때 만 반사 메커니즘 을 통 해 주석 정 보 를 얻 을 수 있 습 니 다. @Target 은 어떤 요소 형식 을 추가 할 수 있 는 지 설명 하 는 데 사 용 됩 니 다.
    SOURCE 는 이 Annotation 형식의 정 보 는 프로그램 소스 코드 에 만 남아 있 고 소스 코드 가 컴 파일 을 거 친 후에 Annotation 의 데 이 터 는 사라 지고 컴 파일 된 class 파일 에 저장 되 지 않 습 니 다.     ClASS 는 이 Annotation 형식의 정 보 를 프로그램 원본 에 저장 하 는 동시에 컴 파일 된. class 파일 에 도 저장 합 니 다. 실행 할 때 이 정 보 를 가상 머 신 (JVM) 에 불 러 오지 않 습 니 다. Annotation 형식의 Retention 값 을 설정 하지 않 았 을 때 시스템 기본 값 은 CLASS 입 니 다.      RUNTIME 은 원본 코드, 컴 파일 된 class 파일 에 정 보 를 저장 하고 실행 할 때 이 정 보 를 JVM 에 불 러 옵 니 다. 
   @Documented 의 목적 은 이 Annotation 형식의 정 보 를 자바 API 설명 문서 에 표시 하 는 것 입 니 다.추가 되 지 않 으 면 javadoc 를 사용 하여 API 문 서 를 생 성 할 때 이 형식 으로 생 성 된 정 보 를 찾 을 수 없습니다. 
   Annotation 의 데 이 터 를 하위 클래스 에 계승 하려 면 @ Inherited 라 는 Annotation 형식 을 사용 합 니 다.
 @ Override 주 해 를 살 펴 보 겠 습 니 다.
4. 567913. 위 에서 알 수 있 듯 이 이 주 해 는 방법 전에 만 사용 할 수 있 고 소스 코드 에 저장 할 수 있 으 며 @ T.. @ R 을. class 파일 에 저장 하지 않 습 니 다. 그러나 역 컴 파일 을 통 해 이 두 주 해 를 출력 할 수 있 습 니까?
 
@ Override 를 사용 할 때 하나의 성명 만 있 으 면 됩 니 다. 매개 변 수 를 전달 하지 않 고 태그 주석 (marker annotation) 이 라 고 부 르 며 특정한 설정 의 미 를 대표 합 니 다.
@ Suppress Warnings ("xxxtype") 를 사용 하여 매개 변 수 를 전달 합 니 다.사실은 이름 값 대구 문 입 니 다. value = "xxxtype" 은 value = 이 문자열 을 생략 합 니 다.
 
모든 Annotation 은 자바. lang. annotation 이라는 인 터 페 이 스 를 자동 으로 계승 하기 때문에 다른 클래스 나 인 터 페 이 스 를 계승 할 수 없습니다. ;Public 또는 기본 값 (default) 두 개의 접근 권한 으로 만 이 주해 류 를 설명 할 수 있 습 니 다.방법의 반환 값 은 기본 형식 (주석 에서 전 달 된 매개 변수 와 연결) byte, short, char, int, long, float, double, boolean 과 String, Enum, Class, annotations 등 데이터 형식 과 이 유형의 배열 만 있 을 수 있 습 니 다.구성원 변수 가 하나 밖 에 없다 면 변수 이름 을 'value' 로 설정 하고 괄호 String value () 를 추가 하 는 것 이 좋 습 니 다. 이렇게 설명 할 때 value 필드 를 생략 할 수 있 습 니 다. 형식적 으로 는 참여 방법 이 없습니다.여러 구성원 변수 뒤에 () 를 추가 해 야 합 니 다. int x () 와 같 습 니 다.
 
설명 주해 류 를 스스로 설계 합 니 다:
@Target(ElementType.METHOD)     
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}

설명 설명 사용 하기:
@Target(ElementType.TYPE)  //     ,      ;  
@Retention(RetentionPolicy.RUNTIME)  //   jvm 
public @interface Description {
	String info();
	String str();
}

주석 보기: 
 
@Description(info="skx",str="good name!!")
public class UseDescription {
}
 주석 처리 과정:
import com. sun. mirror. apt. annotationProcessorFactory 를 깊이 연구 하고 싶 었 습 니 다.@ Deprecated 에 게 알려 졌 습 니 다. 주석 과정 에 대한 상세 한 설명 을 아 는 친구 가 있 으 면 가르쳐 주 십시오.

좋은 웹페이지 즐겨찾기