자바 반사 메커니즘 인식

18810 단어 자바C++cC#J#
자바 반사 메커니즘 인식
     정상 적 인 상황 에서 하나의 종 류 를 알 아야 대상 을 예화 할 수 있 지만 자바 에서 도 하나의 대상 을 통 해 자신 이 있 는 유형의 정 보 를 찾 을 수 있다 면 이것 은 실제 적 으로 Class 류 의 기능 이다.
package zyz.demo;
class X{ };
public class GetClassDemo01{
	public static void main(String args[]){
		X x = new X() ;	//    X    
		System.out.println(x.getClass().getName()) ;	//              
	}
};   
   :zyz.demo.X

 
 
 
 
 
실례 화 Class 유형 대상
클래스 유형 대상 을 실례 화 하 는 방법 은 세 가지 가 있 습 니 다.
첫 번 째: forName () 방법 을 통 해
두 번 째: 클래스. class
세 번 째: 대상. getClass ()
 
package zyz.demo;
class X{
};
public class GetClassDemo02{
	public static void main(String args[]){
		Class<?> c1 = null ;		//     
		Class<?> c2 = null ;		//     
		Class<?> c3 = null ;		//     
		try{
			//                     
			c1 = Class.forName("org.lxh.demo15.getclassdemo.X") ;
		}catch(ClassNotFoundException e){
			e.printStackTrace() ;
		}
		c2 = new X().getClass() ;	//   Object        
		c3 = X.class ;	//    .class   
		System.out.println("   :" + c1.getName());//       
		System.out.println("   :" + c2.getName());//       
		System.out.println("   :" + c3.getName());//       
	}
};

 
클 라 스 류 를 예화 할 수 있 으 면 반사 적 인 추가 작업 을 할 수 있다.
 
1. 실례 화 대상
class Person{
	private String name ;	// name  
	private int age ;		// age  
	public void setName(String name){
		this.name = name ;
	}
	public void setAge(int age){
		this.age = age ;
	}
	public String getName(){
		return this.name ;
	}
	public int getAge(){
		return this.age ;
	}
	public String toString(){	//   toString()  
		return "  :" + this.name + ",  :" + this.age  ;
	}
};
public class Demo01{
	public static void main(String args[]){
		Class<?> c = null ;		//   Class  
		try{
			c = Class.forName("org.lxh.demo15.instancedemo.Person") ;
		}catch(ClassNotFoundException e){
			e.printStackTrace() ;
		}
		Person per = null ;	//   Person  
		try{
			per = (Person)c.newInstance() ;	//      
		}catch(Exception e){
			e.printStackTrace() ;
		}
		per.setName("   ") ;		//     
		per.setAge(30) ;				//     
		System.out.println(per) ;	//     ,  toString()
	}
};
 
 
 
 
     이상 의 코드 를 통 해 키워드 new 대상 을 사용 하지 않 아 도 실례 화 조작, 반사 작용 을 할 수 있 음 을 알 수 있다.그러나 상기 조작 을 사용 할 때 한 가지 주의해 야 할 것 이 있 으 며, 조작 중 류 에는 반드시 무 참 구조 방법 이 존재 해 야 한다.그렇지 않 으 면 실례 화 할 수 없다.
 
     그래서 상기 방법 을 사용 하 는 것 은 실제 적 으로 유형 중의 구조 방법의 지원 이 필요 하고 대상 의 정례 화 수요 에 부합 해 야 한다.
유 참 을 호출 하려 면 다음 절차 에 따라 진행 해 야 합 니 다.
1. Class 류 중의 getConstructors () 를 통 해 본 류 중의 모든 구조 방법 을 얻 을 수 있 습 니 다.
2. 구조 방법 에 대상 배열 을 전달 하고 그 안에 구조 방법 에 필요 한 각 매개 변 수 를 포함한다.
3. 이후 Constructor 를 통한 정례 화 대상
package org.lxh.demo15.instancedemo ;
import java.lang.reflect.Constructor ;	//        
class Person{
	private String name ;	// name  
	private int age ;		// age  
	public Person(String name,int age){
		this.setName(name) ;
		this.setAge(age);
	}
	public void setName(String name){
		this.name = name ;
	}
	public void setAge(int age){
		this.age = age ;
	}
	public String getName(){
		return this.name ;
	}
	public int getAge(){
		return this.age ;
	}
	public String toString(){	//   toString()  
		return "  :" + this.name + ",  :" + this.age  ;
	}
};
public class InstanceDemo03{
	public static void main(String args[]){
		Class<?> c = null ;		//   Class  
		try{
			c = Class.forName("org.lxh.demo15.instancedemo.Person") ;
		}catch(ClassNotFoundException e){
			e.printStackTrace() ;
		}
		Person per = null ;	//   Person  
		Constructor<?> cons[] = null ;
		cons = c.getConstructors() ;
		try{
			//      
			per = (Person)cons[0].newInstance("   ",30) ;	//      
		}catch(Exception e){
			e.printStackTrace() ;
		}
		System.out.println(per) ;	//     ,  toString()
	}
};

 
 
 
     그러나 실제 적 으로 반사 로 대상 의 실례 화 작업 을 하려 면 클래스 에 무 참 구조 가 존재 하 는 것 이 좋다.
 
2. 클래스 가 실현 하 는 모든 인터페이스 획득
 
package org.lxh.demo15.classinfodemo ;
public class GetInterfaceDemo{
	public static void main(String args[]){
		Class<?> c1 = null ;		//   Class  
		try{
			c1 = Class.forName("org.lxh.demo15.Person") ;	//      
		}catch(ClassNotFoundException e){
			e.printStackTrace() ;
		}
		Class<?> c[] = c1.getInterfaces() ;	//               
		for(int i=0;i<c.length;i++){
			System.out.println("       :" + c[i].getName()) ;	//       
		}
	}    
};
  :       :org.lxh.demo15.China

 
3. 부류 취득
package org.lxh.demo15.classinfodemo ;
public class GetSuperClassDemo{
	public static void main(String args[]){
		Class<?> c1 = null ;		//   Class  
		try{
			c1 = Class.forName("org.lxh.demo15.Person") ;	//      
		}catch(ClassNotFoundException e){
			e.printStackTrace() ;
		}
		Class<?> c2 = c1.getSuperclass() ;	//     
		System.out.println("    :" + c2.getName()) ;
	}
};        
  :    :java.lang.Object
 
 
 
4. 취득 류 중의 모든 구조 방법
 
package org.lxh.demo15.classinfodemo ;
import java.lang.reflect.Constructor ;	//         
public class GetConstructorDemo01{
	public static void main(String args[]){
		Class<?> c1 = null ;		//   Class  
		try{
			c1 = Class.forName("org.lxh.demo15.Person") ;	//      
		}catch(ClassNotFoundException e){
			e.printStackTrace() ;
		}
		Constructor<?> con[] = c1.getConstructors() ;	//            
		for(int i=0;i<con.length;i++){
			System.out.println("    :" + con[i]) ;	 //     ,    
		}   
}         	  
};   
  :
    :public org.lxh.demo15.Person()
    :public org.lxh.demo15.Person(java.lang.String)
    :public org.lxh.demo15.Person(java.lang.String,int)

  
   
     이상 의 조작 은 클래스 의 구조 방법 을 얻 었 지만 이 때 는 대상 을 통 해 직접 인쇄 하여 얻 은 것 이 므 로 Constructor 클래스 의 toString () 방법 을 사용 할 것 입 니 다.
     Constructor 클래스 에는 다음 과 같은 몇 가지 방법 이 존재 합 니 다.
    수정자 가 져 오기: public int getModifiers ()
    가 져 오 는 방법 이름: public String getName ()
    매개 변 수 를 가 져 오 는 종류: Public Class [] getParameterTypes()
package org.lxh.demo15.classinfodemo ;
import java.lang.reflect.Constructor ;	//         
public class GetConstructorDemo02{
	public static void main(String args[]){
		Class<?> c1 = null ;		//   Class  
		try{
			c1 = Class.forName("org.lxh.demo15.Person") ;	//      
		}catch(ClassNotFoundException e){
			e.printStackTrace() ;
		}
		Constructor<?> con[] = c1.getConstructors() ;	//            
		for(int i=0;i<con.length;i++){
			Class<?> p[] = con[i].getParameterTypes() ;		//             
			System.out.print("    :" ) ;	 //     ,    
			System.out.print(con[i].getModifiers() + " ") ;	//      
			System.out.print(con[i].getName()) ;	//          
			System.out.print("(") ;
			for(int j=0;j<p.length;j++){
				System.out.print(p[j].getName() + " arg" + i) ;
				if(j<p.length-1){
					//             
					System.out.print(",");	//   “,”
				}
			}
			System.out.println("){}") ;
		}
	}
};

 
 
 
실행 결과:
구조 방법: 1 org. lxh. demo15. Person () {} 구조 방법: 1 org. lxh. demo15. Person (java. lang. String arg 1) {} 구조 방법: 1 org. lxh. demo15. Person (java. lang. String arg 2, int arg 2) {}
이때 조작 후 모든 수정자 가 숫자 로 변 한 것 을 발견 했다.장식 부 호 를 복원 하고 위의 코드 를 고 쳐 써 야 합 니 다.
package org.lxh.demo15.classinfodemo ;
import java.lang.reflect.Constructor ;	//         
import java.lang.reflect.Modifier ;	//         
public class GetConstructorDemo03{
	public static void main(String args[]){
		Class<?> c1 = null ;		//   Class  
		try{
			c1 = Class.forName("org.lxh.demo15.Person") ;	//      
		}catch(ClassNotFoundException e){
			e.printStackTrace() ;
		}
		Constructor<?> con[] = c1.getConstructors() ;	//            
		for(int i=0;i<con.length;i++){
			Class<?> p[] = con[i].getParameterTypes() ;		//             
			System.out.print("    :" ) ;	 //     ,    
			int mo = con[i].getModifiers() ; //          
			System.out.print(Modifier.toString(mo) + " ") ;	//         
			System.out.print(con[i].getName()) ;	//          
			System.out.print("(") ;
			for(int j=0;j<p.length;j++){
				System.out.print(p[j].getName() + " arg" + i) ;
				if(j<p.length-1){
					//             
					System.out.print(",");	//   “,”
				}
			}
			System.out.println("){}") ;
		}
	}
};

 
 
 
 실행 결과:
구조 방법: Public org. lxh. demo15. Person () {} 구조 방법: Public org. lxh. demo15. Person (java. lang. String arg 1) {} 구조 방법: Public org. lxh. demo15. Person (java. lang. String arg 2, int arg 2) {}
 
5. 취득 류 중의 모든 방법
package org.lxh.demo15.classinfodemo ;
import java.lang.reflect.Method ;	//         
import java.lang.reflect.Modifier ;	//         
public class GetMethodDemo{
	public static void main(String args[]){
		Class<?> c1 = null ;		//   Class  
		try{
			c1 = Class.forName("org.lxh.demo15.Person") ;	//      
		}catch(ClassNotFoundException e){
			e.printStackTrace() ;
		}
		Method m[] = c1.getMethods() ;	//       
		for(int i=0;i<m.length;i++){
			Class<?> r = m[i].getReturnType() ;	//        
			Class<?> p[] = m[i].getParameterTypes() ;	//          
			int xx = m[i].getModifiers() ;	//      
			System.out.print(Modifier.toString(xx) + " ") ;	//      
			System.out.print(r + " ") ;
			System.out.print(m[i].getName()) ;
			System.out.print("(") ;
			for(int j=0;j<p.length;j++){
				System.out.print(p[j].getName() + " " + "arg" + j) ;
				if(j<p.length-1){
					System.out.print(",") ;
				}
			}
			Class<?> ex[] = m[i].getExceptionTypes() ;	//     
			if(ex.length>0){ //         
				System.out.print(") throws ") ;
			}else{
				System.out.print(")") ;
			}
			for(int j=0;j<ex.length;j++){
				System.out.print(ex[j].getName()) ;
				if(j<p.length-1){
					System.out.print(",") ;
				}
			}
			System.out.println() ;
		}
	}
};

 
 
실행 결과:
public void sayChina() public class java.lang.String sayHello(java.lang.String arg0,int arg1) public void setAge(int arg0) public int getAge() public class java.lang.String getName() public void setName(java.lang.String arg0) public final void wait() throws java.lang.InterruptedException public final void wait(long arg0,int arg1) throws java.lang.InterruptedException, public final native void wait(long arg0) throws java.lang.InterruptedException public native int hashCode() public final native class java.lang.Class getClass() public boolean equals(java.lang.Object arg0) public class java.lang.String toString() public final native void notify() public final native void notifyAll()  
     일반적인 개발 도구 에서 수필 알림 기능 을 자주 볼 수 있 는데 실제로 이 기능 은 상기 프로그램 을 이용 하여 완 성 된 것 이다.
 
6. 클래스 의 속성 획득
package org.lxh.demo15.classinfodemo ;
import java.lang.reflect.Field ;	//         
import java.lang.reflect.Modifier ;	//         
public class GetFieldDemo{
	public static void main(String args[]){
		Class<?> c1 = null ;		//   Class  
		try{
			c1 = Class.forName("org.lxh.demo15.Person") ;	//      
		}catch(ClassNotFoundException e){
			e.printStackTrace() ;
		}
		{	//     
			Field f[] = c1.getDeclaredFields() ;	//         
			for(int i=0;i<f.length;i++){
				Class<?> r = f[i].getType() ;	//       
				int mo = f[i].getModifiers() ;	//         
				String priv = Modifier.toString(mo) ; //      
				System.out.print("    :") ;
				System.out.print(priv + " ") ;	
				System.out.print(r.getName() + " ") ;	//       
				System.out.print(f[i].getName()) ;	//       
				System.out.println(" ;") ;
			}
		}
		{	//     
			Field f[] = c1.getFields() ;	//           
			for(int i=0;i<f.length;i++){
				Class<?> r = f[i].getType() ;	//       
				int mo = f[i].getModifiers() ;	//         
				String priv = Modifier.toString(mo) ; //      
				System.out.print("    :") ;
				System.out.print(priv + " ") ;	
				System.out.print(r.getName() + " ") ;	//       
				System.out.print(f[i].getName()) ;	//       
				System.out.println(" ;") ;
			}
		}
	}
};

 
 
실행 결과:
이 클래스 속성: private java. lang. String name;이 클래스 속성: private int age;공공 속성: public static final java. lang. String NATIONAL;공공 속성: public static final java. lang. String AUTHOR;
 
7. 반사 호출 클래스 의 방법
    
package org.lxh.demo15.invokedemo ;
import java.lang.reflect.Method ;
public class InvokeSayChinaDemo{
	public static void main(String args[]){
		Class<?> c1 = null ;
		try{
			c1 = Class.forName("org.lxh.demo15.Person") ;	//    Class  
		}catch(Exception e){}
		try{
			Method  met = c1.getMethod("sayChina") ;	//   sayChina()  
			met.invoke(c1.newInstance()) ;	//     
		}catch(Exception e){
			e.printStackTrace() ;
		}
	}
};

 
 
 
     현재 호출 할 방법 에 인자 가 존재 한다 면 매개 변수의 유형 과 내용 을 설정 해 야 합 니 다.
package org.lxh.demo15.invokedemo ;
import java.lang.reflect.Method ;
public class InvokeSayHelloDemo{
	public static void main(String args[]){
		Class<?> c1 = null ;
		try{
			c1 = Class.forName("org.lxh.demo15.Person") ;	//    Class  
		}catch(Exception e){}
		try{
			Method  met = c1.getMethod("sayHello",String.class,int.class) ;	//   sayHello(String name,int age)  
			String rv = null ;
			rv = (String)met.invoke(c1.newInstance(),"   ",30) ;	//     
			System.out.println(rv) ;
		}catch(Exception e){
			e.printStackTrace() ;
		}
	}
};

 
 
 
8. 반사 호출 클래스 setter 및 getter
     Setter 및 Getter 방법 은 표준 속성의 접근 방법 입 니 다. 만약 에 하나의 속성 이 폐쇄 되면 setter 와 getter 방법 을 통 해 설정 하고 얻어 야 합 니 다. 실제로 이 방법의 조작 이 이렇게 규정 해 야 하 는 이 유 는 반사 체제 가 지원 할 수 있 기 때 문 입 니 다.
package org.lxh.demo15.invokedemo ;
import java.lang.reflect.Method ;
public class InvokeSetGetDemo{
	public static void main(String args[]){
		Class<?> c1 = null ;
		Object obj = null ;
		try{
			c1 = Class.forName("org.lxh.demo15.Person") ;	//    Class  
		}catch(Exception e){}
		try{
			obj = c1.newInstance() ;
		}catch(Exception e){}
		setter(obj,"name","   ",String.class) ;	//   setter  
		setter(obj,"age",30,int.class) ;	//   setter  
		System.out.print("  :") ;
		getter(obj,"name") ;
		System.out.print("  :") ;
		getter(obj,"age");
	}
	/**
		Object obj:      
		String att:      
		Object value:        
		Class<?> type:        
	*/

 
 
 
9. 반사 호출 속성
     이상 의 작업 에 서 는 setter 및 getter 방법 지원 이 필요 합 니까?이상 의 조작 호출 은 setter 및 getter 와 무관 하 다 는 것 을 증명 하지만 프로그램의 안전성 을 확보 하기 위해 서 는 setter 및 getter 방법 을 통 해 호출 하 는 것 이 좋 습 니 다.
package org.lxh.demo15.invokedemo ;
import java.lang.reflect.Field ;
public class InvokeFieldDemo{
	public static void main(String args[]) throws Exception{
		Class<?> c1 = null ;
		Object obj = null ;
		c1 = Class.forName("org.lxh.demo15.Person") ;	//    Class  
		obj = c1.newInstance() ;
		Field nameField = null ;
		Field ageField = null ;
		nameField = c1.getDeclaredField("name") ;	//   name  
		ageField = c1.getDeclaredField("age") ;	//   name  
		nameField.setAccessible(true) ;	//         
		ageField.setAccessible(true) ;	//         
		nameField.set(obj,"   ") ;	//   name    
		ageField.set(obj,30) ;			//   age    
		System.out.println("  :" + nameField.get(obj)) ;
		System.out.println("  :" + ageField.get(obj)) ;
	}
};

 
 
 
10. 반사 조작 배열
     반사 메커니즘 은 클래스 에 만 사용 되 는 것 이 아니 라 임의의 인용 데이터 형식 에 도 응용 할 수 있다. 물론 이것 은 배열 을 포함 하고 배열 은 Array 류 를 사용 하여 완성 된다.
     Class 클래스 에는 다음 과 같은 방법 이 있 습 니 다.
public Class getComponentType()

좋은 웹페이지 즐겨찾기