java(19) - 反射机制(一)

2014-11-24 07:32:09 · 作者: · 浏览: 0

一.反射:

反射机制就是java程序在运行时拥有自观能力,能知晓类中的所有属性和方法。

通过反射能得到类中的任何属性和方法,也就是说反射可以打破类的封装特性,可以通过反射来调用私有方法。

让我们看个小例子:

public class Test {
    public static void main(String[] args) throws Exception {
    	
    	
		
    	Class
    classType  = MethodTest.class;
    	
    	Method[]  method = classType.getDeclaredMethods();
    	
    	for(Method m :method){
    		
    		System.out.println(m);
    	}
    	
	}
}


public class MethodTest extends MethodTest2 {
        
	public MethodTest(){}
	   
	public void methodOne(){
		
	}
	private void methodTwo(){
		
	}
	private String methodThree(){
          return null;		
	}
	public int methodFour(){
		return 0;
	}
	
}


打印:

public void Reflection3.MethodTest.methodOne()
private void Reflection3.MethodTest.methodTwo()
private java.lang.String Reflection3.MethodTest.methodThree()
public int Reflection3.MethodTest.methodFour()

这个小例子为我们显示MethodTest类中的所有方法,其中包括了私有方法和普通方法。要想使用反射就必须获得待处理类的class对象。


除了我上面MethodTest.class获取Class对象的方法还有两种,加上我用的一共三种方式:

1).使用Class类的静态方法forName:Class.forName("java.lang.String");

例子:

public>
会打印出String中的所有方法。


2).就是使用我第一个例子中的方法。类.class的方法。


3).使用对象的getClass()方法。


例子:

public class Test {
    public static void main(String[] args) throws Exception {
    	
    	String str = "abc";
		
    	Class
    classType  = str.getClass();
    	
    	Method[]  method = classType.getDeclaredMethods();
    	
    	for(Method m :method){
    		
    		System.out.println(m);
    	}
    	
	}
}

这个将会打印出String类中所有的方法。



如何通过反射使用类中的public类型方法:

public class Test {
       
	  public int sum(int a,int b){
		  
		  return a + b;
	  }
	  
	  public String Course(String str){
		  return "课程名:" + str;
	  }
	  
	  public static void main(String[] args) throws Exception{
		
		  Class
    classType = Test.class;
		  //通过classType.newInstance()来返回Test的实例对象,只能调用无参构造。
		  Object obj = classType.newInstance();
		  //第一个参数指定类中的方法名称,第二个参数指定其方法的参数类型,为什么会有第二个参数,因为类中会有重载的方法,用此来进行区分。
		  Method sumMethod = classType.getMethod("sum",int.class,int.class);
		  
		  Object sum = sumMethod.invoke(obj,1,2);
		  
		  System.out.println((Integer)sum);
		
		  System.out.println("==========================================");
		  
		  Method  courseMethod = classType.getMethod("Course",String.class);
		  
		  Object course  =  courseMethod.invoke(obj,"Java");
		  
		  System.out.println(course);
		  
  	  }
	  
}


打印:

3
==========================================
课程名:Java


上面的例子中通过classType.newInstance()来获得Test的实例,但是这个方法只能调用无参的构造方法。使用方法时用通过invoke(传入方法存在类的实例,传入方法的参数)。

有参的构造方法使用格式:先获得Class对象,然后通过该对象获得相应的Constructor对象,再通过该Constructor对象的newInstance()方法生成。

如果想通过类的带参构造方法生成对象,只能使用下面例子中的格式。

例子:

public class Test {
      public static void main(String[] args) throws Exception {
		
    	  Class
   classType = People.class;
    	  /*
    	   * Constructor con  = classType.getConstructor(new Class[]{});
    	   * Object obj = con.newInstance(new Object[]{});
    	   * 也可以创建不带参数的对象。
    	   */
    	  Constructor con  = classType.getConstructor(String.class);
    	  Object obj = con.newInstance("zhangsan");
    	  System.out.println(obj);
	}
}
class People {
    private String name;
    public People(){}
    public People(String name){
   	 this.name = name;
    }
    public String getName(){
   	 return name;
    }
} 


如何通过反射使用类中的属性和方法:

例子:

public class ReflectionTest {
	   //执行对一个对象的copy操作。
	   public Object copy(Object o) throws Exception{
		    Class
   cs = Student.class;
			Object obj = cs.getConstructor(new Class[]{}).newInstance(new O