zoukankan      html  css  js  c++  java
  • 浅谈反射

    反射

      反射基于Class对象的操作,每个类有且只有一个Class对象。获取Class对象的三种方式,第一,Class.forName("完整的类名");第二,obj.getClass();第三,类名.class。代码如下:

     1      //获取Class对象的第一种方式
     2         Class<Resume> clazz1 = Resume.class;
     3         
     4         //获取Class对象的第二种方式
     5         Resume resume = new Resume();
     6         Class<? extends Resume> clazz2 = resume.getClass();
     7         
     8         //获取Class对象的第三种方式
     9         Class<?> clazz3 = null;
    10         try {
    11             clazz3 = Class.forName("com.sunyard.bean.Resume");
    12         } catch (ClassNotFoundException e) {
    13             e.printStackTrace();
    14         }
    15         
    16         System.out.println(clazz1 == clazz2);
    17         System.out.println(clazz2 == clazz3);
    18         System.out.println(clazz1 == clazz3);

    控制台输出结果:

     1 true 2 true 3 true 

    证明每个类有且只有一个Class对象,也可以说Class对象是一个单例。

    1.利用反射机制获取类中的构造方法,代码如下:

     实体类:

     1 package com.sunyard.bean;
     2 
     3 public class Resume {
     4     private String name;//姓名
     5     private String school;//学校
     6     private String graduateYear;//毕业年份
     7     private int age;//年龄
     8     
     9     private String address;//地址
    10     private String company;//公司
    11     private String timeArea;//工作年限范围
    12     
    13     public Resume(){}
    14     
    15     public Resume(String name){
    16         this.name = name;
    17     }
    18     
    19     public String getName() {
    20         return name;
    21     }
    22     public void setName(String name) {
    23         this.name = name;
    24     }
    25     public String getSchool() {
    26         return school;
    27     }
    28     public void setSchool(String school) {
    29         this.school = school;
    30     }
    31     public String getGraduateYear() {
    32         return graduateYear;
    33     }
    34     public void setGraduateYear(String graduateYear) {
    35         this.graduateYear = graduateYear;
    36     }
    37     public int getAge() {
    38         return age;
    39     }
    40     public void setAge(int age) {
    41         this.age = age;
    42     }
    43     public String getAddress() {
    44         return address;
    45     }
    46     public void setAddress(String address) {
    47         this.address = address;
    48     }
    49     public String getCompany() {
    50         return company;
    51     }
    52     public void setCompany(String company) {
    53         this.company = company;
    54     }
    55     public String getTimeArea() {
    56         return timeArea;
    57     }
    58     public void setTimeArea(String timeArea) {
    59         this.timeArea = timeArea;
    60     }
    61     @Override
    62     public String toString() {
    63         return "Resume [name=" + name + ", school=" + school
    64                 + ", graduateYear=" + graduateYear + ", age=" + age
    65                 + ", address=" + address + ", company=" + company
    66                 + ", timeArea=" + timeArea + "]";
    67     }
    68     
    69 }

     反射操作类:

     1 package com.sunyard.test;
     2 
     3 import java.lang.reflect.Constructor;
     4 
     5 import com.sunyard.bean.Resume;
     6 
     7 public class Test {
     8     public static void main(String[] args) throws Exception {
     9         //1.先获取Class对象
    10         Class c = Resume.class;
    11         //2.通过该类的Class对象创建该类的对象,要求该类中有公共的无参的构造方法
    12         Object obj = c.newInstance();
    13         System.out.println(null == obj ? "创建对象失败" : "创建对象成功");
    14         
    15         //当类中没有空参数的构造方法的时候,要获得类中的构造方法
    16         //获得类中所有公共权限的构造方法
    17         Constructor[] cons = c.getConstructors();//返回此Class对象所表示类的所用公共权限的构造方法
    18         //遍历数组
    19         for(Constructor cc : cons)
    20             System.out.println(cc);
    21         
    22         //获得指定公共权限的构造方法
    23         Constructor con=c.getConstructor(String.class);
    24         //通过指定公共权限的构造方法创建该类的对象
    25         obj=con.newInstance("小明");
    26         System.out.println(obj);
    27         
    28         //获得指定所有权限的构造方法
    29         con = c.getDeclaredConstructor(int.class);
    30         con.setAccessible(true);
    31         obj = con.newInstance(23);
    32         System.out.println(obj);
    33     }
    34 }

    控制台输出:

    1 创建对象成功
    2 public com.sunyard.bean.Resume(java.lang.String)
    3 public com.sunyard.bean.Resume()
    4 Resume [name=小明, school=null, graduateYear=null, age=0, address=null, company=null, timeArea=null]
    5 Resume [name=null, school=null, graduateYear=null, age=23, address=null, company=null, timeArea=null]

    2.反射操作类的属性

     1 package com.sunyard.test;
     2 
     3 import java.lang.reflect.Field;
     4 
     5 public class Test {
     6     public static void main(String[] args) throws Exception {
     7         //1.获取Class对象
     8         Class clazz = Class.forName("com.sunyard.bean.Resume");
     9         //2.通过Class对象创建该类的对象
    10         Object obj = clazz.newInstance();
    11         
    12         //获得类中所有公共权限的属性
    13         Field[] fields = clazz.getFields();
    14         for(Field f : fields)
    15             System.out.println(f);
    16         
    17         System.out.println("--------------------------");
    18         
    19         //获得指定所有权限的属性
    20         Field fName = clazz.getDeclaredField("name");
    21         //取消访问权限的检查
    22         fName.setAccessible(true);
    23         fName.set(obj, "张三");
    24         Object value = fName.get(obj);
    25         System.out.println(value);
    26         
    27         System.out.println("--------------------------");
    28         
    29         //获得类中所有所有权限的属性
    30         fields = clazz.getDeclaredFields();
    31         for(Field f : fields)
    32             System.out.println(f);
    33     }
    34 }

    控制台输出:

     1 --------------------------
     2 张三
     3 --------------------------
     4 private java.lang.String com.sunyard.bean.Resume.name
     5 private java.lang.String com.sunyard.bean.Resume.school
     6 private java.lang.String com.sunyard.bean.Resume.graduateYear
     7 private int com.sunyard.bean.Resume.age
     8 private java.lang.String com.sunyard.bean.Resume.address
     9 private java.lang.String com.sunyard.bean.Resume.company
    10 private java.lang.String com.sunyard.bean.Resume.timeArea

    3.反射操作方法

     1 package com.sunyard.test;
     2 
     3 import java.lang.reflect.Field;
     4 import java.lang.reflect.Method;
     5 
     6 import com.sunyard.bean.Resume;
     7 
     8 public class Test {
     9     public static void main(String[] args) throws Exception {
    10         //1.获取Class对象
    11         Class clazz = Resume.class;
    12         //2.通过Class对象创建该类的对象
    13         Object obj = clazz.newInstance();
    14         
    15         //获取类中所有公共权限的方法(包括继承过来的方法)
    16         Method[] ms = clazz.getMethods();
    17         for(Method m : ms)
    18             System.out.println(m);
    19         
    20         System.out.println("---------------------------");
    21         
    22         //获得指定所有权限的方法
    23         Method getNameMethod = clazz.getMethod("getName", null);
    24         Object value = getNameMethod.invoke(obj, null);
    25         System.out.println(value);
    26     }
    27 }

    控制台输出:

     1 public java.lang.String com.sunyard.bean.Resume.getAddress()
     2 public java.lang.String com.sunyard.bean.Resume.toString()
     3 public java.lang.String com.sunyard.bean.Resume.getName()
     4 public void com.sunyard.bean.Resume.setName(java.lang.String)
     5 public java.lang.String com.sunyard.bean.Resume.getSchool()
     6 public void com.sunyard.bean.Resume.setSchool(java.lang.String)
     7 public java.lang.String com.sunyard.bean.Resume.getGraduateYear()
     8 public void com.sunyard.bean.Resume.setGraduateYear(java.lang.String)
     9 public int com.sunyard.bean.Resume.getAge()
    10 public void com.sunyard.bean.Resume.setAge(int)
    11 public void com.sunyard.bean.Resume.setAddress(java.lang.String)
    12 public java.lang.String com.sunyard.bean.Resume.getCompany()
    13 public void com.sunyard.bean.Resume.setCompany(java.lang.String)
    14 public java.lang.String com.sunyard.bean.Resume.getTimeArea()
    15 public void com.sunyard.bean.Resume.setTimeArea(java.lang.String)
    16 public final void java.lang.Object.wait() throws java.lang.InterruptedException
    17 public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
    18 public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
    19 public native int java.lang.Object.hashCode()
    20 public final native java.lang.Class java.lang.Object.getClass()
    21 public boolean java.lang.Object.equals(java.lang.Object)
    22 public final native void java.lang.Object.notify()
    23 public final native void java.lang.Object.notifyAll()
    24 ---------------------------
    25 null

    4.利用反射进行类型检查

     1 package com.sunyard.test;
     2 
     3 public class Test {
     4     public static void main(String[] args) throws Exception {
     5         Animal d = new Dog();
     6         Animal c = new Cat();
     7         
     8         d.sleep();
     9         c.sleep();
    10         
    11         //为了避免出现类型转换的异常,在转换的时候进行类型检查
    12         //第一种的方式:用到关键字instanceof  是一个运算符,得到的结果是布尔类型的值,boolean b=引用 instanceof 类名
    13         if(d instanceof Dog){
    14             Dog dog=(Dog)d;
    15             dog.lookDoor();
    16         } else {
    17             Cat cat=(Cat)d;
    18             cat.catchMouse();
    19         }
    20         
    21         //第二种方式:用到Class类中的方法isInstance(Object obj)
    22         //如果obj是该Class对象所表示类的对象或者其子类对象时,返回true,否则返回false
    23         Class cc=Dog.class;
    24         if(cc.isInstance(d))
    25         {
    26             Dog dog=(Dog)d;
    27             dog.lookDoor();
    28         }
    29         else
    30         {
    31             Cat cat=(Cat)d;
    32             cat.catchMouse();
    33         }
    34     }
    35 }
    36 
    37 class Animal {
    38     public void sleep(){
    39         System.out.println("动物睡觉");
    40     }
    41 }
    42 
    43 class Dog extends Animal {
    44     @Override
    45     public void sleep() {
    46         System.out.println("狗睡觉");
    47     }
    48     
    49     public void lookDoor(){
    50         System.out.println("看门");
    51     }
    52 }
    53 
    54 class Cat extends Animal {
    55     @Override
    56     public void sleep() {
    57         System.out.println("猫睡觉");
    58     }
    59     
    60     public void catchMouse(){
    61         System.out.println("抓老鼠");
    62     }
    63 }

    反射的基本应用,我曾经在项目中经常运用反射去做一些对象的操作,具体的有以下的几个场景:

    1.通过反射去比较两个对象的每个属性值是否相等

     1 package com.sunyard.test;
     2 
     3 import java.lang.reflect.Method;
     4 import java.util.ArrayList;
     5 import java.util.List;
     6 
     7 public class Test {
     8     public static void main(String[] args) throws Exception {
     9         Person per1 = new Person("李四", 23, "B城市");
    10         Person per2 = new Person("李四", 23, "B城市");
    11         
    12         boolean flag = equalsBean(per1, per2);
    13         System.out.println(flag);
    14     }
    15     
    16     public static boolean equalsBean(Object src,Object dest) throws Exception{
    17         boolean flag = true;
    18         Class<? extends Object> src_clazz = src.getClass();
    19         Class<? extends Object> dest_clazz = dest.getClass();
    20         Method[] src_methods = src_clazz.getMethods();
    21         Method[] dest_methods = dest_clazz.getMethods();
    22         
    23         List<Method> src_list = new ArrayList<Method>();
    24         List<Method> dest_list = new ArrayList<Method>();
    25         for(int i = 0;i < src_methods.length;i++){
    26             if(src_methods[i].getName().startsWith("get")){
    27                 src_list.add(src_methods[i]);
    28             }
    29         }
    30         
    31         for(int i = 0;i < dest_methods.length;i++){
    32             if(dest_methods[i].getName().startsWith("get")){
    33                 dest_list.add(dest_methods[i]);
    34             }
    35         }
    36         
    37         for(int i = 0;i < src_list.size();i++){
    38             Object result = src_list.get(i).invoke(src, null) == null ? "" : src_list.get(i).invoke(src, null);
    39             Object temp = dest_list.get(i).invoke(dest, null) == null ? "" : dest_list.get(i).invoke(dest, null);
    40             if(!result.equals(temp)){
    41                 flag = false;
    42                 break;
    43             }
    44         }
    45         
    46         return flag;
    47     }
    48     
    49 }
    50 
    51 class Person {
    52     private String name;
    53     private int age;
    54     private String address;
    55     
    56     public Person(String name, int age, String address) {
    57         super();
    58         this.name = name;
    59         this.age = age;
    60         this.address = address;
    61     }
    62     
    63     public String getName() {
    64         return name;
    65     }
    66     public void setName(String name) {
    67         this.name = name;
    68     }
    69     public int getAge() {
    70         return age;
    71     }
    72     public void setAge(int age) {
    73         this.age = age;
    74     }
    75     public String getAddress() {
    76         return address;
    77     }
    78     public void setAddress(String address) {
    79         this.address = address;
    80     }
    81     
    82 }

     2.封装JSON工具,详细可以参考我的另外一篇博客 连接为:http://www.cnblogs.com/yujiwei/p/7235773.html

  • 相关阅读:
    更改ORACLE_HOME_NAME
    Linux 查看裸设备大小
    Linux 日常操作
    Linux 高 wio 分析
    Linux 大页: HugePage 与transparent HugePage
    CentOS 8 配置本地YUM源
    MySQL 表压缩
    HIVE 处理json结构数据
    Emacs org-mode 2 文档结构
    CentOS 7 Oracle 19.3 单实例静默安装
  • 原文地址:https://www.cnblogs.com/yujiwei/p/7020794.html
Copyright © 2011-2022 走看看