• Java之反射机制


    java反射机制指的是在java运行过程中,对于任意的类都可以知道他的所有属性以及方法,对于任意一个对象都可以任意的调用他的属性和方法,这种动态获取对象信息和动态调用对象方法的功能称为java反射机制,但是反射使用不当会造成很高的成本。

    反射获取类名称:

    上下代码:

     1 package com.learn.reflect;
     2 /**
     3  * 通过反射获取类名称
     4  * @author Administrator
     5  *
     6  */
     7 public class Test1 {
     8     @SuppressWarnings("unchecked")
     9     public static void main(String[] args) {
    10         // 获取类名称方法一
    11         Class<Test1> c1 = Test1.class;
    12         System.out.println(c1.getName());
    13         
    14         // 获取类名称方法二
    15         Test1 t1=new Test1();
    16         Class<Test1> c2 = (Class<Test1>) t1.getClass();
    17         System.out.println(c2.getName());
    18         
    19         // 获取类名称方法三
    20         try {
    21             Class<Test1> c3 = (Class<Test1>) Class.forName("com.learn.reflect.Test1");
    22             System.out.println(c3.getName());
    23             
    24         } catch (ClassNotFoundException e) {
    25             // TODO Auto-generated catch block
    26             e.printStackTrace();
    27         }
    28         // 以上的 c1,c2,c3是完全一样的,他们都有一个统一的名称:叫做Test1类的类类型。
    29     }
    30 }

    运行结果:

    com.learn.reflect.Test1
    com.learn.reflect.Test1
    com.learn.reflect.Test1

    反射的用处---获取成员方法

    上下代码:

     1 package com.learn.reflect;
     2 
     3 import java.lang.reflect.Method;
     4 
     5 /**
     6  * 反射的用处之获取成员方法
     7  * @author Administrator
     8  *
     9  */
    10 public class Person1 {
    11     private String name="eagle";
    12     private String msg;
    13     
    14     public Person1(String name, String msg) {
    15         this.setName(name);
    16         this.setMsg(msg);
    17     }
    18 
    19     public Person1() {
    20         super();
    21         // TODO Auto-generated constructor stub
    22     }
    23 
    24     public String getName() {
    25         return name;
    26     }
    27 
    28     public void setName(String name) {
    29         this.name = name;
    30     }
    31 
    32     public String getMsg() {
    33         return msg;
    34     }
    35 
    36     public void setMsg(String msg) {
    37         this.msg = msg;
    38     }
    39     
    40     public void say(String name,String msg){
    41         System.out.println(name+"的记录是"+msg);
    42     }
    43     
    44     public static void main(String[] args) {
    45         
    46         try {
    47             // 首先获取类类型
    48             @SuppressWarnings("unchecked")
    49             Class<Person1> c1=(Class<Person1>) Class.forName("com.learn.reflect.Person1");
    50             
    51             try {
    52                 // 通过newInstance()方法生成一个实例
    53                 Object o1=c1.newInstance();
    54                 
    55                 // 获取该类的say方法
    56                 Method m1=c1.getMethod("say",String.class,String.class);
    57                 
    58                 // 通过invoke方法调用该方法
    59                 m1.invoke(o1,"zhangb","准备午休了");
    60                 
    61                 // 得到该类的所有方法,但是不包括父类的方法
    62                 Method[] methods=c1.getDeclaredMethods();
    63                 System.out.println("getDeclaredMethods()方法返回值遍历:");
    64                 for(Method m:methods){
    65                     System.out.println(m.getName());
    66                 }
    67                 System.out.println("------------------");
    68                 
    69                 // 获得该类的所有public方法,包括父类的
    70                 Method[] methodsu=c1.getMethods();
    71                 System.out.println("getMethods()方法返回值遍历:");
    72                 for(Method d:methodsu){
    73                     System.out.println(d.getName());
    74                 }
    75                 
    76             } catch (Exception e) {
    77                 // TODO Auto-generated catch block
    78                 e.printStackTrace();
    79             } 
    80             
    81         } catch (ClassNotFoundException e) {
    82             // TODO Auto-generated catch block
    83             e.printStackTrace();
    84         }
    85     }
    86     
    87 }

    运行结果:

    zhangb的记录是准备午休了
    getDeclaredMethods()方法返回值遍历:
    main
    getName
    setName
    setMsg
    getMsg
    say
    ------------------
    getMethods()方法返回值遍历:
    main
    getName
    setName
    setMsg
    getMsg
    say
    wait
    wait
    wait
    equals
    toString
    hashCode
    getClass
    notify
    notifyAll

    反射的用处---获取成员变量

    上下代码:

     1 package com.learn.reflect;
     2 
     3 import java.lang.reflect.Field;
     4 
     5 /**
     6  * 反射的用处之获取成员变量
     7  * @author Administrator
     8  *
     9  */
    10 public class Person2 {
    11     private String name="eagle";
    12     private String msg;
    13     
    14     public Person2(String name, String msg) {
    15         this.setName(name);
    16         this.setMsg(msg);
    17     }
    18 
    19     public Person2() {
    20         super();
    21         // TODO Auto-generated constructor stub
    22     }
    23 
    24     public String getName() {
    25         return name;
    26     }
    27 
    28     public void setName(String name) {
    29         this.name = name;
    30     }
    31 
    32     public String getMsg() {
    33         return msg;
    34     }
    35 
    36     public void setMsg(String msg) {
    37         this.msg = msg;
    38     }
    39     
    40     public void say(String name,String msg){
    41         System.out.println(name+"的记录是"+msg);
    42     }
    43     
    44     public static void main(String[] args) {
    45         
    46         try {
    47             @SuppressWarnings("unchecked")
    48             Class<Person2> c=(Class<Person2>) Class.forName("com.learn.reflect.Person2");
    49             try {
    50                 Field field = c.getDeclaredField("name");
    51                 Object o1   = c.newInstance();
    52                 /**
    53                  * 由于Person2类中的name变量是private修饰的,
    54                  * 所以需要手动开启允许访问,是public修饰的就不需要设置了
    55                  */
    56                 boolean access = field.isAccessible();
    57                 if(!access){
    58                     field.setAccessible(true);
    59                 }
    60                 
    61                 Object names=field.get(o1);
    62                 System.out.println(names);
    63                 
    64                 // 通过方法getDeclaredFieds()方法来获取所有的成员变量,返回是是一个Field[]数组
    65                 Field[] fields = c.getDeclaredFields() ;
    66                 for(Field f :fields){
    67                     System.out.println("成员变量名:"+f.getName());
    68                 }
    69                 
    70             } catch (Exception e) {
    71                 // TODO Auto-generated catch block
    72                 e.printStackTrace();
    73             } 
    74         } catch (ClassNotFoundException e) {
    75             // TODO Auto-generated catch block
    76             e.printStackTrace();
    77         }
    78         //Field field1
    79     }
    80     
    81 }

    运行结果:

    eagle
    成员变量名:name
    成员变量名:msg

    反射的用处---获取构造方法

    上下代码:

     1 package com.learn.reflect;
     2 
     3 import java.lang.reflect.Constructor;
     4 /**
     5  * 反射的用处之获取构造方法
     6  * @author Administrator
     7  *
     8  */
     9 public class Person3 {
    10     private String name="eagle";
    11     private String msg;
    12     
    13     public Person3(String name, String msg) {
    14         this.setName(name);
    15         this.setMsg(msg);
    16         System.out.println(name+"的描述是"+msg);
    17     }
    18 
    19     public Person3() {
    20         super();
    21         // TODO Auto-generated constructor stub
    22         System.out.println("调用了此构造方法");
    23     }
    24 
    25     public String getName() {
    26         return name;
    27     }
    28 
    29     public void setName(String name) {
    30         this.name = name;
    31     }
    32 
    33     public String getMsg() {
    34         return msg;
    35     }
    36 
    37     public void setMsg(String msg) {
    38         this.msg = msg;
    39     }
    40     
    41     public void say(String name,String msg){
    42         System.out.println(name+"的记录是"+msg);
    43     }
    44     
    45     public static void main(String[] args) {
    46         try {
    47             @SuppressWarnings("unchecked")
    48             Class<Person3> c=(Class<Person3>) Class.forName("com.learn.reflect.Person3");
    49             try {
    50                 Constructor<Person3> c1=(Constructor<Person3>)c.getDeclaredConstructor(String.class,String.class);
    51                 c1.setAccessible(true);
    52                 c1.newInstance("wang123","吃饭");
    53                 
    54             } catch (Exception e) {
    55                 // TODO Auto-generated catch block
    56                 e.printStackTrace();
    57             }
    58         } catch (ClassNotFoundException e) {
    59             // TODO Auto-generated catch block
    60             e.printStackTrace();
    61         }
    62             
    63     }
    64     
    65 }

    运行结果:

    wang123的描述是吃饭

    泛型只是在编译期间起作用,在经过编译进入运行期间是不起作用的。就算是不是泛型要求的类型也是可以插入的。

    反射知识点:

  • 相关阅读:
    李彦宏最新演讲:移动互联网的时代已经结束了
    表值函数 详解
    SQL中PIVOT 行列转换
    将WeX5部署到自己的Tomcat服务器上
    Cordova webapp实战开发:(2)认识一下Cordova
    Cordova webapp实战开发:(1)为什么选择 Cordova webapp?
    甲有5套房,不上班,靠收房租生活;乙有1套房,上班赚工资……(启示)
    Ubuntu 16.04下为Android编译OpenCV 3.1.0 Manager
    Dual Camera Info
    OpenCV 3.1
  • 原文地址:https://www.cnblogs.com/eaglezb/p/6019490.html
一二三 - 开发者的网上家园