Java反射一

1 篇文章 0 订阅

当我大学第一次接触到反射的时候,我就在想下面三个问题。
什么是反射?
反射怎么用?
什么时候用它?
当我弄清楚这三个问题的时候,我突然发现,反射实在太强大,它简直无处不在不管是多大的项目,不论是任何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));
        }
    }

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值