• Java反射机制--笔记


    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("打印类名称:
    " + c.getName() + "
    " + d.getName() + "
    " + m.getName());
     73         System.out.println("不包含包名的类名称:
    " + c.getSimpleName() + "
    " + d.getSimpleName()+ "
    " + 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语言的反射机制。

      

  • 相关阅读:
    MaskRCNN模型解读
    Centos7下WebLogic安装部署
    CentOS 7 安装 JAVA环境(JDK 1.8)
    Linux下如何查看tomcat是否安装、启动、文件路径、进程ID
    Nacos enable to start web server; nested exception is org.springframework.boot.web.server.WebServerException: Unable to start embedded Tomcat
    多线程系列(三)之线程池
    多线程系列(二)之Thread类
    多线程系列(一)之多线程基础
    Vue2/Vue3 自定义组件库
    EF Core使用单独的项目管理迁移
  • 原文地址:https://www.cnblogs.com/huaxingtianxia/p/5564456.html
Copyright © 2020-2023  润新知