首页 > 代码库 > java中反射学习整理

java中反射学习整理

转载请注明:http://blog.csdn.net/j903829182/article/details/38405735

反射主要是指程序可以访问,检测和修改它本身的状态或行为的一种能力。

java中反射是一种强大的工具,它能够创建灵活的代码,这些代码可以在运行时装载,无须在组件之间进行链接。反射允许在编写与执行时,使程序能够接入到jvm中的类的内部信息,而不是源代码中选定的类协作的代码。这使反射成为构建灵活应用代码的主要工具。需要注意的是,如果使用不当,反射的成本会很高。






package com.wj.reflect;

import java.lang.reflect.Array;
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 TestReflect1 {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
        //反射1使用,所有的类的对象都是Class的实例
		ReflectDemo demo=new ReflectDemo();//创建一个对象
	    System.out.println("name="+demo.getClass().getName());//得到对象所属类的路径
	    
	    //定义3个Class的实例
	    Class<?> demo1=null;
	    Class<?> demo2=null;
	    Class<?> demo3=null;
	    
	    //通过三种方式对class对象进行初始化
	    try {
			demo1=Class.forName("com.wj.reflect.ReflectDemo");
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	    
	    demo2=new ReflectDemo().getClass();
	    demo3=ReflectDemo.class;
	    
	    System.out.println("the class name is "+demo1.getName());
	    System.out.println("the class name is "+demo2.getName());
	    System.out.println("the class name is "+demo3.getName());
	    
	    
	    //通过Class的实例对其他的对象进行实例化
	    Class<?> demo4=null;
	    try {
			demo4=Class.forName("com.wj.reflect.ReflectPerson");
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	    ReflectPerson rp=null;
	    try {
			rp=(ReflectPerson) demo4.newInstance();//利用反射机制实例化ReflectPerson的对象
		} catch (InstantiationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	    rp.setName("张三");
	    rp.setSex("男");
	    System.out.println(rp);
	    
	    //通过Class调用其他类中的构造函数 
	    Class<?> demo5=null;
	    try {
			demo5=Class.forName("com.wj.reflect.ReflectPerson");
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	    //定义三个对象
	    ReflectPerson rp1=null;
	    ReflectPerson rp2=null;
	    ReflectPerson rp3=null;
	    //取得ReflectPerson的全部构造函数
	    Constructor<?> cs[]=null;
	    try {
			cs=demo5.getConstructors();
		} catch (SecurityException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	    System.out.println("the first constructs is "+cs[0]);
	    System.out.println("the second constructs is "+cs[1]);
	    System.out.println("the third constructs is "+cs[2]);
	    //利用构造函数进行初始化
	    try {
			rp1=(ReflectPerson) cs[1].newInstance("李四","女");
			rp2=(ReflectPerson) cs[0].newInstance("邓紫棋");
			rp3=(ReflectPerson) cs[2].newInstance();
		} 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("the rp1 is "+rp1);
	    System.out.println("the rp2 is "+rp2);
	    System.out.println("the rp3 is "+rp3);
	    System.out.println("-------------------------");
	    //返回一个类实现的接口
	    Class<?> demo6=null;
	    try {
			demo6=Class.forName("com.wj.reflect.ReflectPerson");
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	    //保存所有接口
	    Class<?>[] inter=demo6.getInterfaces();
	    for(int i=0;i<inter.length;i++){
	    	System.out.println("实现了的接口是"+inter[i].getName());
	    }
	    //取得的父类
	    Class<?> sup=demo6.getSuperclass();
	    System.out.println("the super class is "+sup.getName());
	    
	    
	    System.out.println("-------------------------");
	    //取得构造函数的修饰符
	    Class<?> demo7=null;
	    try {
			demo7=Class.forName("com.wj.reflect.ReflectPerson");
		} catch (ClassNotFoundException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
	    Constructor<?> con[]=null;
	    try {
			con=demo7.getConstructors();
		} catch (SecurityException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	    //打印构造函数
	    for(int i=0;i<con.length;i++){
	    	Class<?>[] para=con[i].getParameterTypes();
	    	System.out.print("构造方法:   ");
	    	/*java.lang.Class.getModifiers()这个类或接口的Java语言修饰符返回整数编码。修饰符包括public, 
	    	 * protected, private,final, static, abstract 和interface及Java虚拟机的常数,
	    	他们应该使用Modifier类的方法进行解码。*/
	    	int modifi=con[i].getModifiers();
	    	System.out.print(Modifier.toString(modifi)+"  ");
	    	System.out.print(con[i].getName());
	    	System.out.print("(");
	    	for(int j=0;j<para.length;j++){
	    		System.out.print(para[j].getName()+"arg"+j);
	    	    if(j<para.length-1){
	    		System.out.print(",");
	    		}
	    	}
	    	System.out.println("){}");
	    }
	    System.out.println("----------------------------------");
	    //获取类里面的所有方法
	    Class<?> demo8=null;
	    try {
			demo8=Class.forName("com.wj.reflect.ReflectPerson");
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	    //获得所有的方法用数组存储
	    Method[] method=demo8.getMethods();
	    for(int i=0;i<method.length;i++){
	    	//获得返回值得类型
	    	Class<?> returnType=method[i].getReturnType();
	    	//获得参数
	    	Class<?> para[]=method[i].getParameterTypes();
	    	//获得方法的修饰符
	    	int tempmodifi=method[i].getModifiers();
	    	System.out.print(Modifier.toString(tempmodifi)+"  ");
	    	System.out.print(returnType.getName()+"  ");
	    	System.out.print(method[i].getName()+" ");
	    	System.out.print("(");
	    	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<?> excep[]=method[i].getExceptionTypes();
	        if(excep.length>0){
	        	System.out.print(") throws ");
	        	for(int k=0;k<excep.length;k++){
	        		System.out.print(excep[k].getName()+"  ");
	        		if(k<excep.length-1){
		    			System.out.print(",");
		    		}
	        	}
	        }else{
	        	System.out.print(")");
	        }
	        System.out.println("{}");
	    }
	    
	    System.out.println("取得类的全部属性----------------------------------");
	    //
	    Class<?> demo9=null;
	    try {
			demo9=Class.forName("com.wj.reflect.ReflectPerson");
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
        System.out.println("----------本类属性----------------");
	    //取得本类的全部属性
        Field[] field=demo9.getDeclaredFields();
        for(int i=0;i<field.length;i++){
        	//权限修饰符
        	int modifi=field[i].getModifiers();
        	//转换成权限类型
        	String fier=Modifier.toString(modifi);
        	//属性类型
        	Class<?> type=field[i].getType();
        	//打印属性的定义
        	System.out.println(fier+" "+type.getName()+
        			" "+field[i].getName()+";");
        }
        System.out.println("--------实现的接口或父类的属性---------------");
	    //取得实现的接口或父类的属性
        Field[] field2=demo9.getFields();
        for(int j=0;j<field2.length;j++ ){
        	//权限修饰符
        	int modifi=field2[j].getModifiers();
        	//转换成权限类型
        	String fier=Modifier.toString(modifi);
        	//属性类型
        	Class<?> type=field2[j].getType();
        	System.out.println(fier+" "+type.getName()+
        			" "+field2[j].getName()+";");
        }
	    
	    
        
        System.out.println("--------通过反射调用其他类中的方法---------------");
        Class<?> demo10=null;
	    try {
			demo10=Class.forName("com.wj.reflect.ReflectPerson");
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	    
	    
	    try {
	    	//调用ReflectPerson的sayChinese()
			Method md=demo10.getMethod("sayChinese");
			try {
				md.invoke(demo10.newInstance());
				//调用ReflectPerson的syaHello
				md=demo10.getMethod("sayHello",String.class,int.class);
				md.invoke(demo10.newInstance(),"zhangsan",23);
			} catch (IllegalArgumentException 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();
			} catch (InstantiationException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
		} catch (SecurityException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	    
	    System.out.println("\n------------调用其他类的set和get方法--------------");
	    Object object=null;
	    try {
			object=demo10.newInstance();
		} catch (InstantiationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	    set(object, "Sex", "男", String.class);
	    get(object,"Sex");
	    
	    System.out.println("\n------------通过反射操作属性--------------");
	    //通过反射操作属性
	    Field f=null;
	    try {
			f=object.getClass().getDeclaredField("sex");
			f.setAccessible(true);
			f.set(object, "女");
			System.out.println("the sex is "+f.get(object));
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} 
	    
	    System.out.println("\n------------通过取得数组并修改数组的信息--------------");
	    int [] array={1,2,3,4,5,6,7,8,9};
	    Class<?> ar=array.getClass().getComponentType();
	    System.out.println("数组类型:"+ar.getName());
	    System.out.println("数组长度:"+Array.getLength(array));
	    System.out.println("数组第一元素:"+Array.get(array, 0));
	    //修改数组第一元素的信息
	    Array.set(array, 0, 100);
	    System.out.println("修改之后数组第一元素:"+Array.get(array, 0));
	    
	    
	    System.out.println("\n------------通过反射修改数组大小--------------");
	    int []newArray=(int[]) arrayUpdateLength(array, 15);
	    print(newArray);
	    System.out.println("\n*********************************");
	    String []str1={"a","b","c","d","e"};
	    String []str2=(String[]) arrayUpdateLength(str1, 10);
	    print(str2);
	    System.out.println("\n------------如何获得类加载器--------------");
	    Load load=new Load();
	    System.out.println("类加载器为:"+load.getClass().getClassLoader().getClass().getName());
	    /*
	     * 其实在java中有三种类类加载器:
	     * 1)Bootstrap ClassLoader 此加载器采用c++编写,一般开发中很少见。
	     * 2)Extension ClassLoader 用来进行扩展类的加载,一般对应的是jre\lib\ext目录中的类
	     * 3)AppClassLoader 加载classpath指定的类,是最常用的加载器。同时也是java中默认的加载器*/
	    
	    
	}
	//修改数组大小
	public static Object arrayUpdateLength(Object object,int len){
		Class<?> array=object.getClass().getComponentType();
		Object newArray=Array.newInstance(array, len);
		int length=Array.getLength(object);
		System.arraycopy(object, 0, newArray, 0, length);
		return newArray;
	}
	
	//打印数组
	public static void print(Object obj){
		Class<?> c=obj.getClass();
		if(!c.isArray()){
			return;
		}
		System.out.println("数组长度为:"+Array.getLength(obj));
	    for(int i=0;i<Array.getLength(obj);i++){
	    	System.out.print(Array.get(obj, i)+" ");
	    }
	}
	
	
	public static void set(Object obj,String attr,
			Object value,Class<?> type){
		try {
			Method method=obj.getClass().getMethod("set"+attr, type);
			method.invoke(obj, value);
		} catch (SecurityException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public static void get(Object ob,String attr){
		try {
			Method method=ob.getClass().getMethod("get"+attr);
			System.out.println(method.invoke(ob));
		} catch (SecurityException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	

}



class Load{
	
}



interface Chinese{
	public static int age=22;
	public void sayChinese();
	public void sayHello(String name,int age);
}




class ReflectPerson implements Chinese{
	private String name;//姓名
	private String sex;//性别
	
	public ReflectPerson() {
		super();
		// TODO Auto-generated constructor stub
	}
	
	public ReflectPerson(String name) {
		super();
		this.name = name;
	}

	public ReflectPerson(String name, String sex) {
		super();
		this.name = name;
		this.sex = sex;
	}
	public void setName(String name){
		this.name=name;
	}
	public String getName(){
		return this.name;
	}
	public String getSex() {
		return sex;
	}
	public void setSex(String sex) {
		this.sex = sex;
	}
	@Override
	public String toString() {
		return "ReflectPerson [name=" + name + ", sex=" + sex + "]";
	}

	@Override
	public void sayChinese() {
		// TODO Auto-generated method stub
		System.out.println("hello, I am is Chinese");
	}

	@Override
	public void sayHello(String name, int age) {
		// TODO Auto-generated method stub
		System.out.println("hello ,my name is "+name+" and my age is "+age);
	}
	
}



class ReflectDemo{
	
}



程序运行结果:

name=com.wj.reflect.ReflectDemo
the class name is com.wj.reflect.ReflectDemo
the class name is com.wj.reflect.ReflectDemo
the class name is com.wj.reflect.ReflectDemo
ReflectPerson [name=张三, sex=男]
the first constructs is public com.wj.reflect.ReflectPerson(java.lang.String)
the second constructs is public com.wj.reflect.ReflectPerson(java.lang.String,java.lang.String)
the third constructs is public com.wj.reflect.ReflectPerson()
the rp1 is ReflectPerson [name=李四, sex=女]
the rp2 is ReflectPerson [name=邓紫棋, sex=null]
the rp3 is ReflectPerson [name=null, sex=null]
-------------------------
实现了的接口是com.wj.reflect.Chinese
the super class is java.lang.Object
-------------------------
构造方法:   public  com.wj.reflect.ReflectPerson(java.lang.Stringarg0){}
构造方法:   public  com.wj.reflect.ReflectPerson(java.lang.Stringarg0,java.lang.Stringarg1){}
构造方法:   public  com.wj.reflect.ReflectPerson(){}
----------------------------------
public  java.lang.String  toString (){}
public  java.lang.String  getName (){}
public  void  setName (java.lang.String arg0){}
public  void  setSex (java.lang.String arg0){}
public  void  sayChinese (){}
public  void  sayHello (java.lang.String arg0,int arg1){}
public  java.lang.String  getSex (){}
public final native  void  wait (long arg0) throws java.lang.InterruptedException  {}
public final  void  wait () throws java.lang.InterruptedException  {}
public final  void  wait (long arg0,int arg1) throws java.lang.InterruptedException  {}
public  boolean  equals (java.lang.Object arg0){}
public native  int  hashCode (){}
public final native  java.lang.Class  getClass (){}
public final native  void  notify (){}
public final native  void  notifyAll (){}
取得类的全部属性----------------------------------
----------本类属性----------------
private java.lang.String name;
private java.lang.String sex;
--------实现的接口或父类的属性---------------
public static final int age;
--------通过反射调用其他类中的方法---------------
hello, I am is Chinese
hello ,my name is zhangsan and my age is 23


------------调用其他类的set和get方法--------------



------------通过反射操作属性--------------
the sex is 女


------------通过取得数组并修改数组的信息--------------
数组类型:int
数组长度:9
数组第一元素:1
修改之后数组第一元素:100


------------通过反射修改数组大小--------------
数组长度为:15
100 2 3 4 5 6 7 8 9 0 0 0 0 0 0 
*********************************
数组长度为:10
a b c d e null null null null null 
------------如何获得类加载器--------------
类加载器为:sun.misc.Launcher$AppClassLoader


参考文章为:http://www.cnblogs.com/rollenholt/archive/2011/09/02/2163758.html