zl程序教程

您现在的位置是:首页 >  后端

当前栏目

Java反射机制--笔记

JAVA笔记反射 -- 机制
2023-09-27 14:20:05 时间

1、认识Class类

任何一个类都是Class类的实例对象,这个实例对象有三种表示方式。

 1         /*java 反射机制*/
 2         // 获取类的方法
 3         UserDao userDao = new UserDao();
 4         Class c = UserDao.class;      // 1、知道类名 使用.class获取类
 5         Class d = userDao.getClass(); // 2、知道对象 使用.getClass()获取类
 6         Class m = null;               // 3、知道类   使用class.forName("")获取类
 7         try {
 8             m = Class.forName("com.description.dao.UserDao");
 9         } catch (ClassNotFoundException e) {
10             e.printStackTrace();
11         }
12 
13         System.out.println("c d是否相等 : " + (c==d));
14         System.out.println("c m是否相等 : " + (c==m));
15 
16         try {
17             UserDao ud = (UserDao) c.newInstance(); // 通过反射实例化一个对象,前提是UserDao必须有一个默认的无参构造方法
18         } catch (InstantiationException e) {
19             e.printStackTrace();
20         } catch (IllegalAccessException e) {
21             e.printStackTrace();
22         }

2、动态加载类实例

新建四个类,一个Software接口,另外新建两个类继承该接口。

Software.java

1 package com.hua.reflect;
2 
3 /**
4  * Created by 华天 on 2016/06/06.
5  */
6 public interface Software {
7     public void show();
8 }
View Code

Word.java

 1 package com.hua.reflect;
 2 
 3 /**
 4  * Created by 华天 on 2016/06/06.
 5  */
 6 public class Word implements Software{
 7 
 8 
 9     @Override
10     public void show() {
11         System.out.println("实现wold功能");
12     }
13 }
View Code

Excel.java

 1 package com.hua.reflect;
 2 
 3 /**
 4  * Created by HuaTian on 2016/06/06.
 5  */
 6 public class Excle implements Software {
 7     @Override
 8     public void show() {
 9         System.out.println("实现Excel功能");
10     }
11 }
View Code

JavaReflect.java

 1  /**
 2      * 动态加载类
 3      */
 4     public static void getClass(String className) {
 5         Software software = null;
 6         try {
 7             Class c = Class.forName("com.hua.reflect."+className);// 获取类
 8             software = (Software) c.newInstance();                // 实例化类
 9         } catch (ClassNotFoundException e) {
10             e.printStackTrace();
11         } catch (InstantiationException e) {
12             e.printStackTrace();
13         } catch (IllegalAccessException e) {
14             e.printStackTrace();
15         }
16         software.show();
17 
18     }
19  public static void main(String[] args){
20    
21     /**
22      * 编译加载类属于静态加载类,运行加载类属于动态加载类
23      * new 对象属于静态加载类,在编译时期就要加载所有可能用到的类。
24      * 通过使用动态加载类,类在使用时加载,不使用不加载。
25      *
26      */
27     JavaReflect.getClass("Word");
View Code

知识点:

  1、编译加载类属于静态加载类,运行加载类属于动态加载类。

  2、new 对象属于静态加载类,在编译时期就要加载所有可能用到的类。 

  3、通过使用动态加载类,类在使用时加载,不使用不加载。

  4、void 等关键字都有类类型。

  5、获取类类型后就能获取类的相关信息。

  6、反射的操作都是编译后的操作。

  7、Java中的泛型是防止错误输入的,只在编译时期有效。ArrayList<String>  == ArrayList

      编译完成后泛型就不存在了,反射可以绕过编译将信息添加进去。

3、获取类中的相关信息

  新建一个ClassUtil.java 帮助类

 1 /**
 2  * Created by 10113513 on 2016/06/06.
 3  */
 4 public class ClassUtil {
 5 
 6     /**
 7      * 显示类的相关信息
 8      * @param obj
 9      */
10     public static void classMessage(Object obj) {
11         Class cs = obj.getClass();
12         System.out.println("类的全名称----------->" + cs.getName());
13         System.out.println("类的简写名称--------->" + cs.getSimpleName());
14     }
15 
16     /**
17      * 显示类中声明的方法
18      * @param obj
19      */
20     public static void getMethods(Object obj){
21         Class cs = obj.getClass();
22         System.out.println("-------"+cs.getName()+"类中的方法");
23         Method[] methods = cs.getDeclaredMethods();
24         String show;
25         for (Method md : methods) {
26             show = md.getName() + md.getReturnType() + "(";
27             Class[] paramType = md.getParameterTypes();
28             for (Class c : paramType) {
29                 show += c.getSimpleName() + ",";
30             }
31             show +=")";
32             System.out.println(show);
33         }
34     }
35 
36     /**
37      * 获取类的成员变量
38      * 只能获取公有的成员变量
39      * @param obj
40      */
41     public static void getFiled(Object obj){
42         Class cs = obj.getClass();
43         System.out.println("-------"+cs.getName()+"类中的成员变量--------");
44         Field[] fds = cs.getFields();
45         for (Field fd:fds) {
46             System.out.println(fd.getName());
47         }
48     }
49 
50     /**
51      * 获取类中的构造函数
52      * @param obj
53      */
54     public static void getConstructor(Object obj){
55         Class cs = obj.getClass();
56         System.out.println("-------"+cs.getName()+"类中的构造函数");
57         Constructor[] ctrs = cs.getConstructors();
58         String show = "";
59         for (Constructor ctr:ctrs) {
60             show += ctr.getName()+"(";
61             Parameter[] pars = ctr.getParameters();
62             for (Parameter par:pars) {
63                 show += par.getName()+",";
64             }
65             show +=")";
66             System.out.println(show);
67         }
68     }
69 
70 }

4、获取方法的相关信息(获取的public的方法)

  1>方法名和参数列表决定了方法的唯一性

  2>方法反射的操作,method.invoke(对象,参数列表)

    1>> 方法没有返回值返回null,又返回值返回具体返回值。

    2>> 方法有参数列表就写成method.invoke(a1,int.class,int.class)  两个参数为例,

       没有参数直接写成method.invoke(a1,int.class,int.class) 。

5、整体代码

JavaReflect.java

  1 package com.hua.reflect;
  2 
  3 import com.description.dao.UserDao;
  4 
  5 
  6 /**
  7  * Created by 华天 on 2016/06/06.
  8  */
  9 public class JavaReflect {
 10     public String animal;
 11     private int num;
 12     protected  boolean isOk;
 13 
 14     public JavaReflect(){
 15 
 16     }
 17     public JavaReflect(String a){
 18         System.out.println("do someThing");
 19     }
 20 
 21 
 22     /**
 23      * 动态加载类
 24      * @param className
 25      */
 26     public static void getClasses(String className) {
 27         Software software = null;
 28         try {
 29             Class c = Class.forName("com.hua.reflect." + className);// 获取类
 30             software = (Software) c.newInstance();                // 实例化类
 31         } catch (ClassNotFoundException e) {
 32             e.printStackTrace();
 33         } catch (InstantiationException e) {
 34             e.printStackTrace();
 35         } catch (IllegalAccessException e) {
 36             e.printStackTrace();
 37         }
 38         software.show();
 39 
 40     }
 41 
 42     /**
 43      * 测试
 44      * @param str
 45      */
 46     public void test(String str) {
 47         System.out.println("这是全部大写的测试方法:"+str.toUpperCase());
 48     }
 49     /**
 50      * 测试1
 51      */
 52     public void test1() {
 53         System.out.println("这是全部小写的测试方法:"+"LIuBaoHua".toLowerCase());
 54     }
 55 
 56 
 57     public static void main(String[] args) {
 58         /*java 反射机制*/
 59         // 获取类的方法
 60         UserDao userDao = new UserDao();
 61         Class c = UserDao.class;      // 1、知道类名 .class
 62         Class d = userDao.getClass(); // 2、知道对象 .getClass()
 63         Class m = null;               // 3、知道类的路径直接 class.forName("");
 64         try {
 65             m = Class.forName("com.description.dao.UserDao"); // 动态加载类
 66         } catch (ClassNotFoundException e) {
 67             e.printStackTrace();
 68         }
 69 
 70         System.out.println("c d是否相等 : " + (c == d));
 71         System.out.println("c m是否相等 : " + (c == m));
 72         System.out.println("打印类名称:\n" + c.getName() + "\n" + d.getName() + "\n" + m.getName());
 73         System.out.println("不包含包名的类名称:\n" + c.getSimpleName() + "\n" + d.getSimpleName()+ "\n" + m.getSimpleName());
 74 
 75         try {
 76 
 77             UserDao ud = (UserDao) c.newInstance(); // 通过反射实例化一个对象,前提是UserDao必须有一个默认的无参构造方法
 78         } catch (InstantiationException e) {
 79             e.printStackTrace();
 80         } catch (IllegalAccessException e) {
 81             e.printStackTrace();
 82         }
 83         /**
 84          * 1、编译加载类属于静态加载类,运行加载类属于动态加载类
 85          * 2、new 对象属于静态加载类,在编译时期就要加载所有可能用到的类。
 86          * 3、通过使用动态加载类,类在使用时加载,不使用不加载。
 87          * 4、void 等关键字都有类类型
 88          * 5、获取类类型后就能获取类的相关信息
 89          */
 90         JavaReflect.getClasses("Word");
 91 
 92         ClassUtil.classMessage(new JavaReflect());
 93 
 94         ClassUtil.getMethods(new JavaReflect());
 95 
 96         ClassUtil.getFiled(new JavaReflect());
 97 
 98         ClassUtil.getConstructor(new JavaReflect());
 99 
100         // 参数列表
101         Class[] parms = new Class[]{String.class};
102         String[] strs = new String[]{"liubaohua"};
103         // 测试有参数
104         ClassUtil.getMethod(new JavaReflect(),"test",parms,strs);
105         // 测试无参数
106         ClassUtil.getMethod(new JavaReflect(),"test1",null,null);
107 
108     }
109 
110 
111 }

ClassUtil.java

  1 package com.hua.reflect;
  2 
  3 import java.lang.reflect.*;
  4 
  5 /**
  6  * Created by 华天 on 2016/06/06.
  7  */
  8 public class ClassUtil {
  9 
 10     /**
 11      * 显示类的相关信息
 12      * @param obj
 13      */
 14     public static void classMessage(Object obj) {
 15         Class cs = obj.getClass();
 16         System.out.println("类的全名称----------->" + cs.getName());
 17         System.out.println("类的简写名称--------->" + cs.getSimpleName());
 18     }
 19 
 20     /**
 21      * 显示类中声明的方法
 22      * @param obj
 23      */
 24     public static void getMethods(Object obj){
 25         Class cs = obj.getClass();
 26         System.out.println("-------"+cs.getName()+"类中的方法");
 27         Method[] methods = cs.getDeclaredMethods();
 28         String show;
 29         for (Method md : methods) {
 30             show = md.getName() + md.getReturnType() + "(";
 31             Class[] paramType = md.getParameterTypes();
 32             for (Class c : paramType) {
 33                 show += c.getSimpleName() + ",";
 34             }
 35             show +=")";
 36             System.out.println(show);
 37         }
 38     }
 39 
 40     /**
 41      * 获取类的成员变量
 42      * 只能获取公有的成员变量
 43      * @param obj
 44      */
 45     public static void getFiled(Object obj){
 46         Class cs = obj.getClass();
 47         System.out.println("-------"+cs.getName()+"类中的成员变量--------");
 48         Field[] fds = cs.getFields();
 49         for (Field fd:fds) {
 50             System.out.println(fd.getName());
 51         }
 52     }
 53 
 54     /**
 55      * 获取类中的构造函数
 56      * @param obj
 57      */
 58     public static void getConstructor(Object obj){
 59         Class cs = obj.getClass();
 60         System.out.println("-------"+cs.getName()+"类中的构造函数");
 61         Constructor[] ctrs = cs.getConstructors();
 62         String show = "";
 63         for (Constructor ctr:ctrs) {
 64             show += ctr.getName()+"(";
 65             Parameter[] pars = ctr.getParameters();
 66             for (Parameter par:pars) {
 67                 show += par.getName()+",";
 68             }
 69             show +=")";
 70             System.out.println(show);
 71         }
 72     }
 73 
 74     /**
 75      * 获取特定的方法
 76      * @param obj 类
 77      * @param mdName 方法名
 78      * @param parms 参数列表
 79      * @param objs 传入参数
 80      */
 81     public static void getMethod(Object obj,String mdName,Class[] parms,Object[] objs){
 82         Class cs = obj.getClass();
 83         System.out.println("----------"+cs.getName()+"类中的具体方操作------------");
 84         try {
 85             JavaReflect ncs = (JavaReflect) cs.newInstance();
 86             // getDeclaredMethod(方法名,参数列表);
 87             Method md = null;
 88             if(parms == null){
 89                 md = cs.getDeclaredMethod(mdName);
 90                 // 调用方法
 91                 md.invoke(ncs);
 92             }else{
 93                 md = cs.getDeclaredMethod(mdName,parms);
 94                 // 调用方法
 95                 md.invoke(ncs,objs);
 96             }
 97         } catch (NoSuchMethodException e) {
 98             e.printStackTrace();
 99         } catch (InvocationTargetException e) {
100             e.printStackTrace();
101         } catch (IllegalAccessException e) {
102             e.printStackTrace();
103         } catch (InstantiationException e) {
104             e.printStackTrace();
105         }
106 
107     }
108 
109 }

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

对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用

对象的方法的功能称为java语言的反射机制。