Java中的反射机制

什么是反射机制?

举个简单的例子,正常情况下如果已经有一个类,则肯定可以通过类创建对象;如果现在要求通过一个对象找到类的名称,此时就要用到反射机制。

Class类的使用:
Class类允许通过一个实例化对象找到一个完整的类信息。常见的用法是:实例化对象,即可以通过一个给定的字符串(包含完整的“包.类”的路径)来实例化一个类的对象;

package com.yxf.classdemos;

class Person{
	String name;
	int age;
}
public class ClassDemos {
	public static void main(String[] args) {
		// TODO Auto-generated method stub
        Class<?> c1 = null;
        Class<?> c2 = null;
        Class<?> c3 = null;
        
        try {
	        c1 = Class.forName("com.yxf.classdemos.Person");
        } catch (ClassNotFoundException e) {
	        // TODO Auto-generated catch block
	        e.printStackTrace();
        }
        c2 = new Person().getClass();
        c3 = Person.class;
        
        System.out.println("Class c1: " + c1.getName());
        System.out.println("Class c2: " + c2.getName());
        System.out.println("Class c3: " + c3.getName());
	}
}
输出结果:

Class c1: com.yxf.classdemos.Person
Class c2: com.yxf.classdemos.Person
Class c3: com.yxf.classdemos.Person

通过反射调用类中的方法:
通过反射调用类中的方法时,需要以下两步骤:
(1)通过Class类的getMethod()方法取得一个Method对象,并设置此方法操作时所需要的参数类型;
    public Method getMethod(String name,Class<?>... parameterTypes) throws NoSuchMethodException,SecurityException
    Parameters:
    name - 所要调用的方法的名字
    parameterTypes - 形参的类型列表
(2)调用invoke(),并向此方法中传递要设置的参数。
    public Object invoke(Object obj,Object... args) throws IllegalAccessException,
            IllegalArgumentException,InvocationTargetException
    Parameters:
    obj - 该方法所在的Class对象
    args - 向该方法传入的实参

通过反射操作属性
在反射机制中也可以直接通过Field类操作类中的属性,通过Field类的set()和get()方法就可以完成设置和取得属性内容的操作。

下面通过例子来说明:

package com.yxf.reflectdemos;

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 ReflectDemos {
	public static void main(String[] args) {
		// TODO Auto-generated method stub
        Class<?> c1 = null;
        try {
	        c1 = Class.forName("com.yxf.reflectdemos.Person");
        } catch (ClassNotFoundException e) {
	        // TODO Auto-generated catch block
	        e.printStackTrace();
        }
        
        Class<?>[] interfaces = c1.getInterfaces(); //取得Person类实现的全部接口
        for(int i = 0; i < interfaces.length; i++){
        	/**Output:
        	 * Interface name:com.yxf.reflectdemos.China
        	 */
        	System.out.println("Interface name:" + interfaces[i].getName());
        }
        
        Class<?> superClass  = c1.getSuperclass();
        /**Output:
         * Super class:java.lang.Object
         */
        System.out.println("Super class:" + superClass.getName());
        
        Constructor<?> con[] = c1.getConstructors();//获取Person类的constructors
        /**Output:
         * Construtor: public com.yxf.reflectdemos.Person(java.lang.String)
         * Construtor: public com.yxf.reflectdemos.Person(java.lang.String,int)
         */
        for(int i = 0; i < con.length; i++){
        	System.out.println("Construtor: " + con[i]);
        }
        
        Person person = null;
        try {
        	//通过反射对Person对象进行初始化
	        person = (Person) con[0].newInstance("xifeng.yang");
        } catch (IllegalArgumentException e) {
	        // TODO Auto-generated catch block
	        e.printStackTrace();
        } catch (InstantiationException e) {
	        // TODO Auto-generated catch block
	        e.printStackTrace();
        } catch (IllegalAccessException e) {
	        // TODO Auto-generated catch block
	        e.printStackTrace();
        } catch (InvocationTargetException e) {
	        // TODO Auto-generated catch block
	        e.printStackTrace();
        }
        System.out.println("--------Person:" + person);
        
        Method[] methods = c1.getMethods();
        /**
         * 输出每一个方法的信息,输出的信息不仅包含了Person类的方法,也把从Object类中继承而来的方法一同进行了输出
         */
        for(int i = 0; i < methods.length;i++){
        	//System.out.println(methods[i]);
        	Class<?> r = methods[i].getReturnType();
        	Class<?> p[] = methods[i].getParameterTypes();
        	int modifiers = methods[i].getModifiers();
        	System.out.print(Modifier.toString(modifiers) + " ");
        	System.out.print(r.getName() + " ");
        	System.out.print(methods[i].getName());
        	System.out.print("(");
        	for(int x = 0; x < p.length;x++){
        		System.out.print(p[x].getName() + " " + "arg " + x);
        		if(x < p.length -1){
        			System.out.print(",");
        		}
        	}
        	
        	Class<?> ex[] = methods[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 < ex.length - 1){
        			System.out.print(",");
        		}
        	}
        	System.out.println();
        }
        
        Field[] f = c1.getDeclaredFields();//取得本类的属性
        for(int i = 0; i < f.length;i++){
            System.out.println(f[i]);
        }
        
        Field[] publicFileds = c1.getFields(); //取得父类的公共属性
        for(int i = 0; i < f.length;i++){
            System.out.println(publicFileds[i]);
        }
        /*通过反射调用类中的方法*/
        try {
	        Method method = c1.getMethod("sayChina");
	        method.invoke(con[1].newInstance("xifeng.yang",28));
	        
	        Method method2 = c1.getMethod("sayHello",String.class,int.class);
	        method2.invoke(con[1].newInstance("xifeng.yang",28), "Chris.Yang",30);
        } catch (Exception e) {
	        // TODO Auto-generated catch block
	        e.printStackTrace();
        } 
        /*通过反射操作属性*/
        Field nameField = null;
        Field ageField = null;
        try {
        	Object obj = c1.newInstance();
	        nameField = c1.getDeclaredField("name");
	        ageField = c1.getDeclaredField("age");
	        
	        nameField.setAccessible(true);//将name属性设置为可被外部访问的
	        ageField.setAccessible(true);//将age属性设置为可被外部访问的
	        
	        nameField.set(obj,"Tao.Lo");
	        ageField.set(obj, 50);
	        System.out.println("---Name: " + nameField.get(obj));
	        System.out.println("---Age: " + ageField.get(obj));
        } catch (Exception e) {
	        // TODO Auto-generated catch block
	        e.printStackTrace();
        } 
	}
}
package com.yxf.reflectdemos;

interface China{
	public static final String NATION = "China";
	public static final String AUTHOR = "xifeng.yang";
	public void sayChina();
	public String sayHello(String name, int age);
}

public class Person implements China{
    private String name;
	private int age;
	
	public Person(String name, int age){
		this.name = name;
		this.age = age;
				
	}
	
	public Person(String name){
		this(name, 0);
		this.name = name;
	}
	
	public Person(){
		this(null,0);
	}
	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 "name: " + this.name + ", age: " + this.age;
	}
	
	@Override
    public void sayChina() {
	    // TODO Auto-generated method stub
		System.out.println("------sayChina()");
	    System.out.println("Author: " + AUTHOR + ", NATION: " + NATION);
    }
	
	@Override
    public String sayHello(String name, int age) {
	    // TODO Auto-generated method stub
		System.out.println("------sayHello()");
	    return name + ", Hello! I am " + age + "years old now!";
    }
}
参考文献:

《Java开发实战经典(名师讲坛)》

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值