首页 > 代码库 > Java反射机制

Java反射机制

反射机制的作用

            一般机制是java知道类的定义(比如import了这个类,或者就在同一个包里),然后根据类定义去new一个实例出来。而反射机制是不知道类是什么样的,根据字符串之类的类名字等去获取一个实例,然后根据方法名字去执行方法。好比说,一般情况下画一只老虎,我得先知道老虎长什么样子才能画出来;有了反射机制,我只要知道“老虎”这个名字就能画出来,可以知道老虎吃什么,有什么能力,有什么属性。

反射机制的功能

(这些类都位于java.lang.reflect包中)

Class类:代表一个类。(java.lang.Object java.lang.Class<T>T - 由此 Class 对象建模的类的类型。例如,String.class 的类型是 Class<String>。如果将被建模的类未知,则使用 Class<?>。)

Field类:代表类的成员变量(提供有关类或接口的单个字段的信息,以及对它的动态访问权限。反射的字段可能是一个类(静态)字段或实例字段。)

Method类:代表类的方法。(Method 提供关于类或接口上单独某个方法(以及如何访问该方法)的信息。所反映的方法可能是类方法或实例方法(包括抽象方法)。)

Construct类:代表类的构造方法。(提供关于类的单个构造方法的信息以及对它的访问权限。)

Array类:提供动态的创建数组,以及访问数组中元素的静态方法。


创建测试类

package com.gqx.Reflect;

class Person {
	private String name;
	public int age;
	 public int add(int para1,int para2){
			return para1+para2;
		}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	 public String toString(){
		 return "["+this.name+"    "+this.age+"]";
	 }
	 public Person(String name, int age) { 
	        this.age=age; 
	        this.name=name; 
	    } 
	 public Person() { 
	  
	    } 
	 
	 public String say(String message){
		 return message;
	 }
	
	 
}

以下开始使用

java.lang.Object
  java.lang.Class<T>的方法
package com.gqx.Reflect;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

public class Demo3 {

	public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, InstantiationException, NoSuchFieldException {
		// TODO Auto-generated method stub
		//获取类的Class对象
		Class<?> demo1=Class.forName("com.gqx.Reflect.Person");
		Class<?> demo2=new Person().getClass();
		Class<?> demo3=Person.class;
		
		
		/**
		 * 获取Field
		 */

		// 使用getFields获取属性(公共字段的 Field 对象的数组)  
		Field[] fields = demo1.getFields();  
		for (Field f : fields)  
		{  
		    System.out.println(f);  
		} 
		// 使用getDeclaredFields获取属性  
		fields = demo1.getDeclaredFields();  
		for (Field f : fields)  
		{  
		    System.out.println(f);  
		} 
		
		
		/**
		 * 获取类的Method
		 */
		System.out.println("===============类的全部方法===============");
		//返回一个包含某些 Method 对象的数组,这些对象反映此 Class 对象所表示的类或接口
		//(包括那些由该类或接口声明的以及从超类和超接口继承的那些的类或接口)的公共 member 方法。
		Method[] method = demo1.getMethods();  
		for (int i = 0; i < method.length; ++i) {
            Class<?> returnType = method[i].getReturnType();
            Class<?> para[] = method[i].getParameterTypes();
            int temp = method[i].getModifiers();
            //取得修饰符
            System.out.print(Modifier.toString(temp) + " ");
            //取得返回类型
            System.out.print(returnType.getName() + "  ");
            //取得方法名称
            System.out.print(method[i].getName() + " ");
            System.out.print("(");
            //取得c参数
            for (int j = 0; j < para.length; ++j) {
                System.out.print(para[j].getName() + " " + "arg" + j);
                if (j < para.length - 1) {
                    System.out.print(",");
                }
            }
            //是否存在异常
            Class<?> exce[] = method[i].getExceptionTypes();
            if (exce.length > 0) {
                System.out.print(") throws ");
                for (int k = 0; k < exce.length; ++k) {
                    System.out.print(exce[k].getName() + " ");
                    if (k < exce.length - 1) {
                        System.out.print(",");
                    }
                }
            } else {
                System.out.print(")");
            }
            System.out.println();
        }
		
		System.out.println();  
		   
		
		/**
		 * 获取类的Constructor
		 */
		System.out.println("*****************");
		// 使用getDeclaredConstructors获取构造器   
		//返回一个包含某些 Constructor 对象的数组,这些对象反映此 Class 对象所表示的类的所有公共构造方法。
		Constructor<?>[] constructors = demo1.getConstructors();  
		for (Constructor<?> m : constructors)  
		{  
		    System.out.println(m);  
		}
		// 使用getDeclaredConstructors获取构造器     
		constructors = demo1.getDeclaredConstructors();  
		for (Constructor<?> m : constructors)  
		{  
		    System.out.println(m);  
		}       
		
		/**
		 * 新建类的实例
		 */
		
		System.out.println("*****************");
		//想调用方法,必须去获得method方法
		/**
		 * getMethod(String name, Class<?>... parameterTypes) 
          *返回一个 Method 对象,它反映此 Class 对象所表示的类或接口的指定公共成员方法。
          *String:方法的名字,
          *Class<?>... parameterTypes:该方法需要接受的参数,数组的形式,
          *因为java中的方法会根据参数个数容易出现重载。
		 */
		Object demo=demo3.newInstance();
		Method addMethod=demo3.getMethod("add",new Class[ ]{int.class,int.class} );
		Object result=addMethod.invoke(demo, new Object[]{1,2});
		System.out.println((Integer)result);
		
		/**
		 * 获取某个类的全部属性
		 */
		System.out.println("===============本类属性===============");
		Field[] field = demo1.getDeclaredFields();
        for (int i = 0; i < field.length; i++) {
            // 权限修饰符
            int mo = field[i].getModifiers();
            String priv = Modifier.toString(mo);
            // 属性类型
            Class<?> type = field[i].getType();
            System.out.println(priv + " " + type.getName() + " " + field[i].getName() + ";");
        }
        
        System.out.println("==========私有的属性==========");
        // 取得实现的接口或者父类的属性
        Field[] filed1 = demo1.getFields();
        for (int j = 0; j < filed1.length; j++) {
            // 权限修饰符
            int mo = filed1[j].getModifiers();
            String priv = Modifier.toString(mo);
            // 属性类型
            Class<?> type = filed1[j].getType();
            System.out.println(priv + " " + type.getName() + " " + filed1[j].getName() + ";");
    } 
}
	
	

}

  

通过反射机制操作某个类的属性

package com.gqx.Reflect;

import java.lang.reflect.Field;

public class Demo4 {
	private String proprety = null;
	public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchFieldException, SecurityException {
		// TODO Auto-generated method stub
		Class<?> clazz = Class.forName("com.gqx.Reflect.Demo4");
        Object obj = clazz.newInstance();
        // 可以直接对 private 的属性赋值
        Field field = clazz.getDeclaredField("proprety");
        field.setAccessible(true);
        field.set(obj, "Java反射机制");
        System.out.println(field.get(obj));
	}

}

  

 

 

 

Java反射机制