Java 反射机制

来源:互联网 发布:驱鼠器 知乎 编辑:程序博客网 时间:2024/06/16 02:37

一.什么是反射机制?

JAVA反射机制是指在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。

二.反射有关的API有哪些?

Class,Method,Field,Constructor,Annotation,Package,Interface等;

获取一个类的Class对象,从Class对象中可以获得类字段信息,方法,构造函数,注解,父类和接口等信息.还可以执行方法,获取属性值等.

三.如何使用反射获取类信息?

获取一个类的Class对象,从Class对象中可以get类字段信息,方法,构造函数,注解,父类和接口等信息.还可以执行方法,获取属性值等.

下面函数列出了通过Class可以获得的信息.

  1: /**
  2:    * getMethods(Class.class,"get"); 反射获取clss类的包含前缀pre的方法
  3:    * 
  4:    * @param clazz
  5:    * @param pre
  6:    */
  7:   public static void getMethods(Class<?> clazz, String pre) {
  8:     Method[] ms = clazz.getDeclaredMethods();
  9:     for (Method m : ms) {
 10:       if (m.getName().contains(pre)) {
 11:         System.out.println(m);
 12:       }
 13:     }
 14:   }

四.如何动态实例化对象?

有两种方式:

1.通过Class的newInstance()方法实例化,类必须包含参构造方法.

2.通过Class选择一个Constructor,执行Constructor的newInstance()实例化;

 

  1: /**
  2:    * 使用构造函数需要预先知道有哪些构造函数
  1: /**
  3:    * @throws Exception
  4:    */
  5:   public static void createObject2() throws Exception {
  6:     Class<?> clazz=Class.forName("java.io.BufferedInputStream");
  7:     Constructor ctor=clazz.getConstructor(InputStream.class);
  8:     InputStream in=InstanceObjectDemo.class.getClassLoader().getResourceAsStream("InstanceObjectDemo.java");
  9:     BufferedInputStream obj=(BufferedInputStream) ctor.newInstance(in);
 10:     System.out.println(obj);
 11:     obj.close();
 12:   }
 13:   /**
 14:    * 动态实例化对象
 15:    * @param clazz
 16:    */
 17:   public static Object createObject(String className){
 18:     Object obj=null;
 19:     try {
 20:       obj=Class.forName(className).newInstance();
 21:     } catch (Exception e) {
 22:       e.printStackTrace();
 23:     }
 24:     return obj;
 25:   }

五.动态方法调用

使用Method的invoke()方法执行public的方法,对于私有方法,要先调用setAccessible(true)取消访问权限检查.

  1: /**
  2:    * 执行方法invoke()
  3:    * @throws Exception
  4:    */
  5:   public static void excMethon() throws Exception{
  6:     
  7:     String str="12abcde";
  8:     Class clazz=str.getClass();
  9:     Method m=clazz.getMethod("substring", int.class);
 10:     String result=(String) m.invoke(str, 2);
 11:     System.out.println(result);
 12:   }

六.如何访问成员变量值?

  1: /**
  2:    * 直接获取字段值,需要取消访问权限[setAccessible(true)] 
  3:    * 类Point2中有x,y两个整型字段
  4:    * @throws Exception
  5:    */
  6:   public static void accessField()throws Exception{
  7:     Point2 p=new Point2(2,3);
  8:     Class clazz=p.getClass();
  9:     Field fx=clazz.getDeclaredField("x");
 10:     Field fy=clazz.getDeclaredField("y");
 11:     
 12:     fx.setAccessible(true);
 13:     fy.setAccessible(true);
 14:     
 15:     System.out.println(fx.get(p)+","+fy.get(p));
 16:     fx.set(p, 20);
 17:     
 18:     fy.set(p, 30);
 19:     System.out.println(p);
 20:     
 21:   }

七.数组反射工具类java.lang.reflect.Array

  1: /**
  2:    * 动态操作数组
  3:    * @throws Exception
  4:    */
  5:   public static void createArray()throws Exception{
  6:     Object arr=Array.newInstance(Integer.class, 10);
  7:     Array.set(arr, 1, 100);
  8:     Array.set(arr, 2, 200);
  9:     Array.set(arr, 3, 300);
 10:     System.out.println(Array.get(arr, 1));
 11:     System.out.println(Array.get(arr, 2));
 12:   }

八.综合示例-通过文件实例化对象

  1: 
  2: import java.io.FileInputStream;
  3: import java.lang.reflect.InvocationTargetException;
  4: import java.lang.reflect.Method;
  5: import java.util.ArrayList;
  6: import java.util.HashMap;
  7: import java.util.List;
  8: import java.util.Map;
  9: import java.util.Properties;
 10: 
 11: /**
 12:  * 通过属性文件实例化对象并赋值.
 13:  * @author WeiCong
 14:  *
 15:  */
 16: public class ObjectPoolFactory {
 17: 
 18:   private Map<String ,Object> objectPool=new HashMap<String,Object>();
 19:   private Properties config=new Properties();
 20:   
 21:   public static void main(String[] args) {
 22:     ObjectPoolFactory objectFactory=new ObjectPoolFactory();
 23:     objectFactory.load("config.properties");
 24:     try {
 25:       objectFactory.initPool();
 26:       objectFactory.setProperty();
 27:       Student s=(Student)objectFactory.getObject("student");
 28:       Person p=s.getPerson();
 29:       System.out.println(p);
 30:       System.out.println(s);
 31:     } catch (Exception e) {
 32:       e.printStackTrace();
 33:     }
 34:   }
 35:   /**
 36:    * 加载配置文件
 37:    * @param filename
 38:    */
 39:   public void load(String filename){
 40:     try(
 41:       FileInputStream in=new FileInputStream(filename);
 42:     ){
 43:       config.load(in);
 44:     }catch(Exception e){
 45:       e.printStackTrace();
 46:     }
 47:   }
 48:   /**
 49:    * 根据类完整限定名创建对象
 50:    * @param className
 51:    * @return
 52:    * @throws ClassNotFoundException
 53:    * @throws InstantiationException
 54:    * @throws IllegalAccessException
 55:    */
 56:   private  Object createObject(String className) throws ClassNotFoundException, InstantiationException, IllegalAccessException{
 57:     Class clazz=Class.forName(className);
 58:     return clazz.newInstance();
 59:   }
 60:   /**
 61:    * 创建配置文件中的所有实例
 62:    * @throws ClassNotFoundException
 63:    * @throws InstantiationException
 64:    * @throws IllegalAccessException
 65:    */
 66:   public void initPool() throws ClassNotFoundException, InstantiationException, IllegalAccessException{
 67:     for(String name : config.stringPropertyNames()){
 68:       if(!name.contains("%")){
 69:         String className=config.getProperty(name);
 70:         Object obj=createObject(className);
 71:         objectPool.put(name, obj);
 72:       }
 73:     }
 74:   }
 75:   /**
 76:    * 获取一个对象
 77:    * @param classKey
 78:    * @return
 79:    */
 80:   public Object getObject(String classKey){
 81:     return objectPool.get(classKey);
 82:   }
 83:   /**
 84:    * 为对象赋值
 85:    * @throws NoSuchMethodException
 86:    * @throws SecurityException
 87:    * @throws IllegalAccessException
 88:    * @throws IllegalArgumentException
 89:    * @throws InvocationTargetException
 90:    */
 91:   public void setProperty() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException{
 92:     for(String name : config.stringPropertyNames()){
 93:       if(name.contains("%")){
 94:         String[] values=config.getProperty(name).split(",");
 95:         String[] tmp=name.split("%");
 96:         String classKey=tmp[0];
 97:         String propertyName=tmp[1];
 98:         String methodName="set"+propertyName.substring(0, 1).toUpperCase()+propertyName.substring(1, propertyName.length());
 99:         Object obj=getObject(classKey);
100:         //
101:         for(Method m : obj.getClass().getDeclaredMethods()){
102:           if(methodName.equals(m.getName())){
103:             if(m.getParameterTypes().length==values.length){
104:               Object[] args=getParams(values,m.getParameterTypes());
105:               m.invoke(obj,args);
106:             }
107:           }
108:         }
109:       }
110:     }
111:   }
112:   private Object[] getParams(String[] values, Class<?>[] parameterTypes) {
113:     List<Object> list=new ArrayList<Object>();
114:     for(int i=0;i<values.length;i++){
115:       list.add(transform(values[i],parameterTypes[i]));
116:     }
117:     return list.toArray();
118:   }
119:   private Object transform(String string, Class<?> clazz) {
120:     //1.判断是否为基本类型
121:     if(clazz == Integer.class||clazz == int.class){
122:       return Integer.valueOf(string);
123:     }else if(clazz==Double.class||clazz == double.class){
124:       return Double.valueOf(string);
125:     }else if(clazz==Float.class||clazz == float.class){
126:       return Float.valueOf(string);
127:     }else if(clazz==String.class){
128:       return (string);
129:     }else if(clazz==Character.class||clazz==char.class){
130:       return string.charAt(0);
131:     }else if(clazz==Boolean.class||clazz==boolean.class){
132:       return Boolean.valueOf(string);
133:     }else if(clazz==Long.class||clazz==long.class){
134:       return Long.valueOf(string);
135:     }else if(clazz==Short.class||clazz==short.class){
136:       return Short.valueOf(string);
137:     }else if(clazz==Float.class||clazz==float.class){
138:       return Float.valueOf(string);
139:     }else{
140:       //判断是否为容器中的其他类型
141:       if(objectPool.containsKey(string)){
142:         return objectPool.get(string);
143:       }
144:     }
145:     return null;
146:   }
147: }

Bean

  1: package zhwcong.javase.reflect;
  2: /**
  3:  * Bean
  4:  * @author WeiCong
  5:  *
  6:  */
  7: public class Person {
  8:   private String name;
  9:   private int height;
 10:   private int weight;
 11:   private boolean marry;
 12:   private double every;
 13:   public boolean isMarry() {
 14:     return marry;
 15:   }
 16:   public void setMarry(boolean marry) {
 17:     this.marry = marry;
 18:   }
 19:   public double getEvery() {
 20:     return every;
 21:   }
 22:   public void setEvery(double every) {
 23:     this.every = every;
 24:   }
 25:   public String getName() {
 26:     return name;
 27:   }
 28:   public void setName(String name) {
 29:     this.name = name;
 30:   }
 31:   public int getHeight() {
 32:     return height;
 33:   }
 34:   public void setHeight(int height) {
 35:     this.height = height;
 36:   }
 37:   public int getWeight() {
 38:     return weight;
 39:   }
 40:   public void setWeight(int weight) {
 41:     this.weight = weight;
 42:   }
 43:   public String toString(){
 44:     return "[name='"+name+"',weight='"+weight+"',height='"+height+"',marry='"+marry+"',every='"+every+"']";
 45:   }
 46: }
 47: 
  1: package zhwcong.javase.reflect;
  2: 
  3: public class Student {
  4:   private Person person;
  5:   
  6:   private int no;
  7: 
  8:   public Person getPerson() {
  9:     return person;
 10:   }
 11: 
 12:   public void setPerson(Person person) {
 13:     this.person = person;
 14:   }
 15: 
 16:   public int getNo() {
 17:     return no;
 18:   }
 19: 
 20:   public void setNo(int no) {
 21:     this.no = no;
 22:   }
 23: 
 24:   @Override
 25:   public String toString() {
 26:     return "[no='"+no+"',person='"+person+"']";
 27:   }
 28:   
 29:   
 30: }
 31: 
config.properties
  1: person=zhwcong.javase.reflect.Person
  2: person%weight=100
  3: person%height=180
  4: person%name=zhang
  5: person%marry=true
  6: person%every=12.33
  7: student=zhwcong.javase.reflect.Student
  8: student%person=person
  9: student%no=11

九.一个AOP的简单示例.

  1: 
  2: 
  3: import java.lang.reflect.InvocationHandler;
  4: import java.lang.reflect.Method;
  5: import java.lang.reflect.Proxy;
  6: 
  7: public class MyAop {
  8:   public static void main(String[] args) throws Exception {
  9:     CInterface c=new C();
 10:     CInterface p=(CInterface) ProxyFactory.getProxy(c);
 11:     p.f1();
 12:     p.f2();
 13:   }
 14: }
 15: //5.自定义一个代理工厂
 16: class ProxyFactory{
 17:   public static Object getProxy(Object target)throws Exception{
 18:     MyInvocationHander h=new MyInvocationHander();
 19:     h.setTarget(target);
 20:     return Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),h);
 21:   }
 22: }
 23: //4.实现InvocationHandler的invoke方法
 24: class MyInvocationHander implements InvocationHandler{
 25:   private Object target;
 26:   public void setTarget(Object target) {
 27:     this.target = target;
 28:   }
 29:   @Override
 30:   public Object invoke(Object proxy, Method method, Object[] args)
 31:       throws Throwable {
 32:     G g = new G();
 33:     g.before();
 34:     Object obj=method.invoke(target, args);
 35:     g.after();
 36:     return obj;
 37:   }
 38: }
 39: //1.目标类接口
 40: interface CInterface{
 41:   public void f1();
 42:   public void f2();
 43: }
 44: //2.目标类
 45: class C implements CInterface{
 46:   public void f1(){
 47:     System.out.println("f1");
 48:   }
 49:   public void f2(){
 50:     System.out.println("f2");
 51:   }
 52: }
 53: //3.通用操作
 54: class G{
 55:   public void before(){
 56:     System.out.println("===在方法前执行===");
 57:   }
 58:   public void after(){
 59:     System.out.println("===在方法后执行===");
 60:   }
 61: }
0 0
原创粉丝点击