zoukankan      html  css  js  c++  java
  • Java反射机制(获取Class对象的三种方式+获取Class中的构造函数进行对象的初始化+获取反射类的字段+获取反射类的一般方法)

      反射技术其实就是动态加载一个指定的类,并获取该类中的所有内容。而且将字节码文件封装成对象,并将字节码文件中的内容都封装成对象,这样便于操作这些成员,简单来说:反射技术可以对一个类进行解剖,反射大大增强了应用程序的可扩展性。

          反射技术的原理如下图所示:

    但是要想要对字节码文件进行解剖,必须要有字节码文件对象. 如何获取字节码文件对象呢?

    要读取的类文件源码:

     1 package Reflect;
     2 
     3 public class Person {
     4 
     5     /**
     6      * @param args
     7      */
     8     private String name;
     9     private int age;
    10     public Person(){
    11         System.out.println("Construcor run..");
    12     }
    13     public Person(String name,int age){
    14     this.name=name;
    15     this.age=age;
    16     System.out.println("Person param run...");
    17     }
    18     public static void method(){
    19         System.out.println("method run...");
    20     }
    21     public static void paramMethod(String name,int age){
    22         System.out.println("name="+name+"age:"+age);
    23     }
    24     public static void staticMethod(){
    25         System.out.println("static run");
    26     }
    27     public void show(){
    28         System.out.println(name+"Method show run.."+age);
    29     }
    30 
    31 }

    获取字节码文件对象有三种方式:

    (1)
     /*
      * 获取字节码对象的方式:
      * 1,Object类中的getClass()方法的。
      * 想要用这种方式,必须要明确具体的类,并创建对象。
      * 麻烦 
      */

    1 public static void getObject_1() {
    2         Person p=new Person();
    3         Class<? extends Person> classz=p.getClass();
    4         System.out.println(classz);
    5         Person p1=new Person();
    6         Class<? extends Person> classz1=p.getClass();
    7         System.out.println(classz1);
    8         System.out.println(classz==classz1);
    9     }

    (2)
     /*
      * 方式二:
      * 任何数据类型(基本数据类型和引用数据类型)都具备一个静态的属性.class来获取其对应的Class对象。
      * 相对简单,但是还是要明确用到类中的静态成员。
      * 还是不够扩展。
      *
      */

    1 public  static void getObject_2() {
    2     
    3         Class classz=Person.class;
    4         Class classz1=Person.class;
    5         System.out.println(classz==classz1);
    6     }

    (3)

     /*
      * 方式三:
      * 只要通过给定的类的 字符串名称就可以获取该类,更为扩展。
      * 可是用Class类中的方法完成。
      * 该方法就是forName.
      * 这种方式只要有名称即可,更为方便,扩展性更强。
      */

    1 public  static void getObject_3() throws ClassNotFoundException {
    2         String classname="Reflect.Person";
    3         Class classz=Class.forName(classname);
    4         System.out.println(classz);
    5     }

    获取Class中的构造函数初始化对象:

    (1)调用空参数的构造函数:使用Class类中的newInstance()方法

     //早期:new时候,先根据被new的类的名称找寻该类的字节码文件,并加载进内存,
      // 并创建该字节码文件对象,并接着创建该字节文件的对应的Person对象.

    1   //现在:
    2   String name = "cn.itcast.bean.Person";
    3   //找寻该名称类文件,并加载进内存,并产生Class对象。
    4   Class clazz = Class.forName(name);
    5   //如何产生该类的对象呢?
    6   Object obj  = clazz.newInstance();

    (2)调用带参数的构造函数:先要获取指定参数列表的构造函数对象,然后通过该构造函数的对象的newInstance(实际参数)进行对象的初始化

    /*
       * 当获取指定名称对应类中的所体现的对象时,
       * 而该对象初始化不使用空参数构造该怎么办呢?
       * 既然是通过指定的构造 函数进行对象的初始化,
       * 所以应该先获取到该构造函数。 通过字节码文件对象即可完成。
       * 该方法是:getConstructor(paramterTypes);
       * 
       */
    1 //带参数初始化新创建的对象
    2     public  static void createNewObject_param() throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
    3         String classname="Reflect.Person";
    4         Class classz=Class.forName(classname);
    5         Constructor constructor=classz.getConstructor(String.class,int.class);
    6         constructor.newInstance("Java",30);
    7     }

     获取反射类的字段:

     1     public static void getFiledDemo() throws ClassNotFoundException,
     2             NoSuchFieldException, SecurityException, InstantiationException,
     3             IllegalAccessException {
     4         Class classz = Class.forName("Reflect.Person");
     5         Field field = null;
     6         field = classz.getDeclaredField("age");
     7         field.setAccessible(true);
     8         Object obj = classz.newInstance();
     9         field.set(obj, 89);
    10         Object o = field.get(obj);
    11         System.out.println(o);
    12     }

    获取反射类的成员方法:

    (1)获取空参数一般方法

     1 private static void getMethodDemo_2() throws Exception {
     2         Class clazz = Class.forName("Reflect.Person");
     3 
     4         Method method = clazz.getMethod("show", null);// 获取空参数一般方法。
     5 
     6         // Object obj = clazz.newInstance();
     7         Constructor constructor = clazz.getConstructor(String.class, int.class);
     8         Object obj = constructor.newInstance("linux", 37);
     9 
    10         method.invoke(obj, null);
    11     }

    (2)获取带参数的一般方法

     1 private static void getMethodDemo_3() throws Exception {
     2 
     3         Class clazz = Class.forName("Reflect.Person");
     4 
     5         Method method = clazz.getMethod("paramMethod", String.class, int.class);
     6 
     7         Object obj = clazz.newInstance();
     8 
     9         method.invoke(obj, "Ruby", 89);
    10     }


    (3)获取反射类的公有、私有方法

    1 private static void getMethodDemo() throws ClassNotFoundException {
    2         Class classz = Class.forName("Reflect.Person");
    3         Method[] methods = classz.getMethods();// 获取反射类中所有共有的方法
    4         methods = classz.getDeclaredMethods();// 获取本类中包括私有的所有的方法
    5         for (Method method : methods) {
    6             System.out.println(method);
    7         }
    8     }

    本文为博主原创文章,转载请注明出处:http://www.cnblogs.com/ysw-go/
    1、本博客的原创原创文章,都是本人平时学习所做的笔记,如有错误,欢迎指正。
    2、如有侵犯您的知识产权和版权问题,请通知本人,本人会即时做出处理文章。
    3、本博客的目的是知识交流所用,转载自其它博客或网站,作为自己的参考资料的,感谢这些文章的原创人员

  • 相关阅读:
    高性能网站优化-确保异步加载脚本时保持执行顺序
    sublime安装和汉化
    解决IE6下a标签的onclick事件里的超链接不跳转问题
    C++大数据处理
    HDRtools-OpenExr
    Effective C++学习进阶版
    我的算法学习之路
    一个应届计算机毕业生的2012求职之路
    存储器管理
    程序员的自我修养——操作系统篇
  • 原文地址:https://www.cnblogs.com/ysw-go/p/5335948.html
Copyright © 2011-2022 走看看