Java反射一

来源:互联网 发布:ubuntu如何挂载u盘 编辑:程序博客网 时间:2024/05/16 07:20

当我大学第一次接触到反射的时候,我就在想下面三个问题。
什么是反射?
反射怎么用?
什么时候用它?
当我弄清楚这三个问题的时候,我突然发现,反射实在太强大,它简直无处不在不管是多大的项目,不论是任何Java框架,反射都在里面充当着必不可少的角色。
回到最初的三个问题。
第一、什么反射?
其实简单的说反射就是动态的获取或修改类的信息(包括类)。我相信每个Java coder都知道java分编译时和运行时,通常情况下coder都是静态的定义或获取类的信息,这种情况下定义的类都会在编译时被编译器编译。但是反射是在运行时获取或加载类的信息,它可以让你动态的修改一些已经定义好的类信息。

第二、反射怎么用?
反射怎么用,就和平常写代码一样,获取一个类的实例,初始化类的信息,然后调用类的方法,将一些参数传入要调用的方法内。对,没错,就是这么简单,只不过反射换了一种方式来做这些事情。当地是什么方式呢,让我们来看个demo一探究竟吧。
首先写了一个bean.

public class Student implements Serializable {    private Integer id;    private String name;    private int age;    private String depart;    private Date birthday;    private String gender;    public Student() {        // TODO Auto-generated constructor stub    }    public   Student(String name,int age,String depart){        this.name= name;        this.age = age;        this.depart = depart;    } /*省略getter setter method*/  public String toString(){    return "name:"+this.name+             "\n age:"+this.age+"\n depart:"+this.depart;  }  public void writeSome(String name){      System.out.println("name:"+name);  }  public void writeSome(String name,String depart){      System.out.println("name:"+name+"\t depart:"+depart);  }}

用下面的代码动态获取类信息。

    Class<?> clazz = Class.forName("com.hal.entity.Student");            Field[] fields = clazz.getDeclaredFields();            for (Field field : fields) {                System.out.println("field name:"+field.getName());            }            Method[] methods = clazz.getDeclaredMethods();            for (Method method : methods) {                System.out.println("method name:"+method.getName());            }

这是输出信息:
*field name:id
field name:name
field name:age
field name:depart
field name:birthday
field name:gender
method name:toString
method name:getName
method name:getId
method name:setName
method name:writeSome
method name:writeSome
method name:setId
method name:getAge
method name:setAge
method name:getDepart
method name:setDepart
method name:getBirthday
method name:setBirthday
method name:getGender
method name:setGender*
当然还有很多其他的方法,具体的请看API.
反射还能实现代理或者动态加载方法。

        Object object = clazz.newInstance();        System.out.println(object.getClass().getName());            Method method = clazz.getDeclaredMethod("writeSome",String.class);            method.invoke(object,"steven");

Object object = clazz.newInstance()就是初始化对象了,相当于new一个对象。
getDeclaredMethod(String paramString, Class<?> paramArrayOfClass)
第一个参数是方法名,第二个参数是一个可变长参数,是指方法的参数类型。

运行该段代码就会加载bean中的这个方法:
public void writeSome(String name){
System.out.println(“name:”+name);
}

第三、什么时候用反射
学了东西肯定要使用出来才能产生价值,但是也不能乱用,不然反而会适得其反。其实大家无时无刻都在用着反射,反射也总是在帮coder提高效率。
- JDK的动态代理
- cglib基于类的代理
- Spring 的AOP
- 依赖注入
- 属性拷贝
等等。底层大部分都是用反射来实现了。
记住,当需要动态获取或修改一些类信息时,就可以使用反射来完成。

最后附上一段动态改变数组长度的demo

    public static void main(String[] args) {        // TODO Auto-generated method stub      int[] arr = (int[])intitalArray();      print(arr);      int[] newArr =(int[]) changeArrayLength(arr, 10);      print(newArr);    }    private static Object intitalArray(){        int[] arr = {1,2,3,4,5};        return arr;    }    private static Object changeArrayLength(Object object,int len){        Class<?> clazz = object.getClass();        System.out.println(clazz);        Object newArr = Array.newInstance(clazz, len);        int newlen = Array.getLength(object);        System.arraycopy(object, 0, newArr,5, newlen);        return newArr;    }    private static void print(Object object){        Class<?> clazz = object.getClass();        if (!clazz.isArray()) {            return;        }        int len =Array.getLength(object) ;        System.out.println("array length: "+len);        for (int i = 0; i < len; i++) {            System.out.println(Array.get(object, i));        }    }

以上纯属个人理解,如有任何问题,还望指正。
谢谢。

0 0
原创粉丝点击