[java] java 中的反射

JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;

对于任意一个对象,都能够调用它的任意一个方法和属性;

这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。

一、一个简单例子获取类的包名和类名:

package com.wa.java.book.kernel.reflect;

/**
 * Created by Administrator on 2015/2/7.
 */
public class Hello {

    public static void main(String[] args){

        Baby baby = new Baby();
        String pack = baby.getClass().getName();//获取完成的类名(包含包名)
        String simpleName = baby.getClass().getSimpleName();//获取类名
        String canonical = baby.getClass().getCanonicalName();
        System.out.println(pack);//com.wa.java.book.kernel.reflect.Baby
        System.out.println(simpleName);//Baby
        System.out.print(canonical);//com.wa.java.book.kernel.reflect.Baby
      /*看源码getName()和getSimpleName()和getCanonicalName()的区别是类是否是数组*/
        String[] ary ={"JAVA","SPRING","HIBERNATE"};

        System.out.println(ary.getClass().getName());//com.wa.java.book.kernel.reflect.Baby[Ljava.lang.String;
        System.out.println(ary.getClass().getSimpleName());//String[]
        System.out.println(ary.getClass().getCanonicalName());//java.lang.String[]
    }
}

 class Baby{



}

另外附上以上方法的源码:

  public String getName() {
    if (name == null)
        name = getName0();
    return name;
    }

    // cache the name to reduce the number of calls into the VM
    private transient String name;
    private native String getName0();


public String getSimpleName() {
    if (isArray())
        return getComponentType().getSimpleName()+"[]";

    String simpleName = getSimpleBinaryName();
    if (simpleName == null) { // top level class
        simpleName = getName();
        return simpleName.substring(simpleName.lastIndexOf(".")+1); // strip the package name
    }



public String getCanonicalName() {
    if (isArray()) {
        String canonicalName = getComponentType().getCanonicalName();
        if (canonicalName != null)
        return canonicalName + "[]";
        else
        return null;
    }
    if (isLocalOrAnonymousClass())
        return null;
    Class<?> enclosingClass = getEnclosingClass();
    if (enclosingClass == null) { // top level class
        return getName();
    } else {
        String enclosingName = enclosingClass.getCanonicalName();
        if (enclosingName == null)
        return null;
        return enclosingName + "." + getSimpleName();
    }
    }

二、实例化class:

  /*实例化class对象*/
    @Test
    public void test1(){


        Date date = new Date();
        Class  dateClass = date.getClass();
        System.out.println(dateClass.getName());//java.util.Date
        System.out.println(new Integer(1).getClass().getName());//java.lang.Integer
        System.out.println(Calendar.class.getName());//java.util.Calendar
        //获取父类
        System.out.println(Integer.class.getSuperclass().getName());//java.lang.Number

          /*
          类名写错出现java.lang.ClassNotFoundException: java.utl.Date
          * 通过类加载器加载类的完整包名
          * */
        String str = "java.util.Date";
        Class<Date> clazz= null; try {
            clazz = (Class<Date>) Class.forName(str);
            System.out.println(clazz.getCanonicalName());
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }


    }

运行结果:

java.util.Date
java.lang.Integer
java.util.Calendar
java.lang.Number
java.util.Date

三、通过反射实例化对象:

package com.wa.java.book.kernel.reflect;

import java.util.Date;
import java.util.List;

/**
 * Created by Administrator on 2015/2/7.
 */
public class Father {

    private String name ;
    private Date birthday;
    private String address;
    private Integer age ;
    private Boolean isLoveYou;

    public Father(){}
    public Father(String name){
        this.name=name;
    }
  //省略getter和setter方法

    @Override
    public String toString() {
        return "Father{" +
                "name='" + name + '\'' +
                ", birthday=" + birthday +
                ", address='" + address + '\'' +
                ", age=" + age +
                ", isLoveYou=" + isLoveYou +
                '}';
    }
}
 /*通过反射实例化对象*/
    @Test
    public void test2(){

        String str ="com.wa.java.book.kernel.reflect.Father";
        try {
            Class<?> clazz = Class.forName(str);
            //通过默认构造器实例化对象
            /**
             * 如果没有默认构造器抛出异常:
             * java.lang.InstantiationException: com.wa.java.book.kernel.reflect.Father

             */
           Father f= (Father) clazz.newInstance();
            f.setName("老爸");
            f.setAddress("家乡");
            f.setAge(60);
            f.setBirthday(new SimpleDateFormat("yyyy-MM-dd").parse("1960-01-10"));
            f.setIsLoveYou(true);
            System.out.println(f);
            //Father{name='老爸', birthday=Sun Jan 10 00:00:00 CST 1960, address='家乡', age=60, isLoveYou=true}

        } catch (Exception e) {
            e.printStackTrace();
        }

    }

实例化的类必须包含默认构造器,否则抛出以下异常:

java.lang.InstantiationException: com.wa.java.book.kernel.reflect.Father
    at java.lang.Class.newInstance0(Class.java:340)
    at java.lang.Class.newInstance(Class.java:308)
    at com.wa.java.book.kernel.reflect.TestReflect.test2(TestReflect.java:56)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:157)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:74)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:211)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:67)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)

四、获取构造器,属性,方法

  /*获取构造器,属性和方法*/
    @Test
    public void test3(){


       Constructor<?>[] cons= Father.class.getDeclaredConstructors();
        for(int i=0;i<cons.length;i++){
            /*
            获取所有的构造器
    public com.wa.java.book.kernel.reflect.Father(java.lang.String)
public com.wa.java.book.kernel.reflect.Father()*/
            System.out.println(cons[i]);

        }
        /**
         * 获取类的所有属性
         * private java.util.Date com.wa.java.book.kernel.reflect.Father.birthday
         private java.lang.String com.wa.java.book.kernel.reflect.Father.address
         private java.lang.Integer com.wa.java.book.kernel.reflect.Father.age
         private java.lang.Boolean com.wa.java.book.kernel.reflect.Father.isLoveYou
         */
        Field[] fields = Father.class.getDeclaredFields();
        Method[] methods=Father.class.getDeclaredMethods();
        for(int i=0;i<fields.length;i++){
            System.out.println(fields[i]);
        }
        /*只获取l类的属性名*/

        String name = fields[0].getName();
        System.out.println(name);


/*获取所有的方法
*

public void com.wa.java.book.kernel.reflect.Father.setAge(java.lang.Integer)
public void com.wa.java.book.kernel.reflect.Father.setBirthday(java.util.Date)
public void com.wa.java.book.kernel.reflect.Father.setIsLoveYou(java.lang.Boolean)
public java.util.Date com.wa.java.book.kernel.reflect.Father.getBirthday()
public java.lang.Integer com.wa.java.book.kernel.reflect.Father.getAge()
public java.lang.Boolean com.wa.java.book.kernel.reflect.Father.getIsLoveYou()
public java.lang.String com.wa.java.book.kernel.reflect.Father.getAddress()
public java.lang.String com.wa.java.book.kernel.reflect.Father.toString()
public java.lang.String com.wa.java.book.kernel.reflect.Father.getName()
public void com.wa.java.book.kernel.reflect.Father.setName(java.lang.String)
public void com.wa.java.book.kernel.reflect.Father.setAddress(java.lang.String)
* */
        for (int j=0;j<methods.length;j++){
            System.out.println(methods[j]);
        }

    }

五、通过反射为对象的某个属性赋值:

 /*通过构造器实例化对象并赋值*/
    @Test
    public void test4() throws Exception{

       Field[] fields =Father.class.getDeclaredFields();
         Father father = new Father();
        Object[] values = {"团聚了..",new SimpleDateFormat("yyyy-MM-dd").parse("1943-12-43"),
                "老家",54,true};
        String[] clazz ={"String","Date","String","Integer","Boolean"};

        for(int i=0;i<fields.length;i++){
            //获取指定的set方法
            String setMethods ="set"+Character.toUpperCase(fields[i].getName().charAt(0))+fields[i].getName().substring(1);
            //指定方法名和参数类型
            Method method = Father.class.getDeclaredMethod(setMethods,fields[i].getType());
            //为指定的方法赋值
            method.invoke(father,values[i]);
        }

        //Father{name='团聚了..', birthday=Wed Jan 12 00:00:00 CST 1944, address='老家', age=54, isLoveYou=true}

        System.out.println(father);

    }

 

参考资料:

 

http://q.cnblogs.com/q/64609/

 

http://www.cnblogs.com/rollenholt/archive/2011/09/02/2163758.html

posted @ 2015-02-08 00:06  snow__wolf  阅读(183)  评论(0)    收藏  举报