• 反射机制--总结


    1.反射的概念:

       Reflection(反射) 被视为 动态语言的关键,反射机制允许程序在执行的时候借助Reflection的API 获取任何类的内部信息,直接操作任何对象的内部属性和方法。

    2.Object类中定义Class 类:反射从程序允许结果看:利用Java编译生成.class文件反编译原来的Java---通过对象反射求出类的名称

     

     1). 反射的理解:反射通过动态的设置内部的属性和方法,在反射的过程中,我们事先不知道 类的名称是什么,采用getClass() 方法获取一个实体的类型---在JavaBean过程中反射的类必须有一个无参的构造器:同时在反射的时候属性和方法的名称保持一致

    对getClass(): Object 类一个方法名叫getClass,利用该方法获取一个实例的 类型类 类型类指的是代表一个类型的类,String类型的类String.class

    java 中所有的类型类是Class的实体

       getClass():一个类的实例具备的方法.getClass() 是动态的;解释:返回这个对象正在运行是的类,直到这个对象属于什么类

       Class()方法是一个类的方法是静态的方法

    总结:

       1. 对Class 实例的理解

         正常情况:创建一个类,通过编译(javac.exe),生成对应的class文件,之后使用Java.exe(JVm 类加载器)运行.class 文件

         反射情况:此class文件加载到内存以后就是一个运行时类 , 存在缓存区域,那么此运行时类就是一个Class 的实例;对某个对象.getClass() 为了得到这个运行时类  注意每一个运行类只加载一次  Person.Java--编译--Person.class(Class 的实例)

     2.获取Class 实例 clazz作用:

          1).创建对应的运行时类的对象 clazz.newInstance();

           2).对应运行时类的完整结构

           3).调用指定的属性,方法和构造器

           4).反射的应用 动态的代理


      1.Java中有四种方法获取反射的机制:

        1.调用运行时类的本身的.class的属性:静态

         Class clazz=Person.class;

       2.通过运行时对象获取:动态

         Person per=new Person();

         Class clazz=per.getClass();

     3. 通过Class 的静态的方法

      Class.forName("com.atug.Person");

    4.通过类的加载器

    Class clazz=this.getClass().getClassLoader().loadClass("com.atug.Person");

     1    Person person=new Person();
     2         // 1.第一种方式通过Object的getClass() 方法(需要实例化一个对象)
     3         Class clazz1=person.getClass();
     4         
     5         // 2.通过对象实例方法获取(需要实例化一个对象)
     6         Class clazz2=Person.class;
     7         
     8         // 类的全路径
     9         try {
    10             Class clazz3=Class.forName("com.atug.reflection_1.Person");
    11         } catch (ClassNotFoundException e) {
    12             // TODO Auto-generated catch block
    13             e.printStackTrace();
    14         }
    15         

    2.Class 实例第一种作用:

       2.1创建类的对象:调用Class对象的new Instance()的方法:

         1)类必须误差构造器  2).类的构造器的访问权限必须足够

    反射类没有空的构造器,报错 ;类的构造器是非private权限

    通过反射获取对象的内部成员的属性,不理睬private

     1 // 1.第一种方式通过Object的getClass() 方法(需要实例化一个对象)
     2           Class clazz=Person.class;
     3         
     4           5          //.getFields 只能获取其中 public属性
     6           Field[] fields=clazz.getDeclaredFields();
     7         
     8           for(Field fi:fields)
     9           {
    10               System.out.println(fi.getName());
    11           }
    12           
    13           //同样获取运行的方法
    14           Method[] m1=clazz.getDeclaredMethods();
    15           for(Method m:m1)
    16           {
    17               System.out.println(m.getName());
    18           }
    19           

    事实上:利用反射的主要目的不在获取内部属性或者是内部方法名称 在于利用反射动态的建立一个对象,在其中设置成员属性和调用其中成员方法

     2.2. 因此首先 反射动态的建立一个类的对象 Person p=clazz.newInstance(); 调用类型方法时候注意private 同时Method.invoke() 启动反射建立的实例的方法

     1  // 利用反射的主要目的不在获取内部属性或者是内部方法名称 在于利用反射动态的建立一个对象,在其中设置成员属性和调用其中成员方法
     2           // 1.利用反射调用指定的属性  私有成员Declared
     3           Person p=(Person) clazz.newInstance();
     4           Field f1=clazz.getDeclaredField("name");
     5           f1.setAccessible(true);
     6           f1.set(p,"HuHui");
     7           System.out.println(p);
     8           
     9           // 2.利用反射生成某个实例调用其中的方法 paramterTypes=show 类型 void null
    10           Method M1=clazz.getDeclaredMethod("show");
    11           M1.setAccessible(true);
    12           M1.invoke(p);

     4.对加载器的理解:

      程序主动使用某个类的时候,该类没有被加载到内存,使用getClassLoader().loadClass();

    类加载器将类加载到内存:启动型加载器和自定义加载器

       Java核心库String是引导类加载器

    使用类加载器从 某个目录下得得到 properties

     1 ClassLoader loader1=this.getClass().getClassLoader();
     2         System.out.println(loader1);
     3         // 类加载器加载某个目录下的Java
     4         InputStream is=loader1.getResourceAsStream("com\atug\properties");
     5         // 当前工作空间小
     6         FileInputStream in=new FileInputStream(new File("jdbc.properties"));
     7         Properties pro=new Properties();
     8         pro.load(is);
     9         
    10         String name=pro.getProperty("XXX");
    11     }

     3.反射第二个事情: 反射获取类的完整的结构:实现全部接口,所继承的父类 全部的Field

        常用反射获取泛型的类型

      3.1 获取属性,获取权限修饰符 变量类型 变量名

      

    
    
     1         Class clazz=Person.class;
     2         
     3         //Person 类比较的复杂继承 和泛型接口
     4         Field [] fields=clazz.getFields();
     5         
     6         // 查看一下getFields 只能获取运行本类和父类中声明public属性 null
     7         for(Field field:fields)
     8         {
     9             System.out.println(field.getName());
    10         }
    11         
    12         // 2. 获取所有声明的属性,如果修改属性值必须field.setAccessible(arg0);
    13         Field [] fields1=clazz.getDeclaredFields();
    14         for(Field field:fields1)
    15         {
    16             
    17             System.out.println(field);
    18             
    19             System.out.println(field.getName());
    20             // 1.获取修饰符
    21             System.out.println(Modifier.toString(field.getModifiers()));
    22             
    23             // 2.获取属性的类型:
    24             Class Type=field.getType();
    25             System.out.println(Type.getName());
    
    
    
     

    3.2 获取运行时候的父类---发现得到父类的名称 父类有泛型并没有显示出来

    1 Class clazz=Person.class;
    2         
    3         Class superClass=clazz.getSuperclass();
    4         System.out.println(superClass.getName());

    3.3 获取带泛型的父类 父类的类型: getGenericsuperClass();获取父类泛型--返回Type类型

     1 Class clazz=Person.class;
     2         Type type=clazz.getGenericSuperclass();
     3         
     4         System.out.println(type);
     5         
     6         //--------重点:获取父类的泛型 String-----
     7         // ParameterizedType 是Type的子类 --带有参数化的Type
     8         
     9         if(type instanceof ParameterizedType)
    10         {
    11              ParameterizedType param=( ParameterizedType)type;
    12              
    13              // 获取带参数Type 中实际参数类型 返回数组有多个参数 
    14              Type[] types=param.getActualTypeArguments();
    15              if(types[0] instanceof Class)
    16                     System.out.println(types[0].getTypeName());
    17         }

    DAO 直到操作的那个类,获取父类的泛型 反射建立对象将SQL中数据存到JavaBean中。

  • 相关阅读:
    JavaScript垃圾回收机制
    clientHeight ,offsetHeight,style.height,scrollHeight有区别与联系
    win10家庭版安装Docker
    jacoco代码覆盖率报告分析
    jenkins build
    NoSuchAlgorithmException
    记一次单元测试问题com.sun.crypto.provider.HmacSHA1 cannot be cast to javax.crypto.MacSpi
    Mockito入门:如何在Spring中Mock部分对象
    H2数据UNIX_TIMESTAMP兼容问题
    java
  • 原文地址:https://www.cnblogs.com/woainifanfan/p/6715691.html
Copyright © 2020-2023  润新知