博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java反射机制(获取Class对象的三种方式+获取Class中的构造函数进行对象的初始化+获取反射类的字段+获取反射类的一般方法)...
阅读量:7154 次
发布时间:2019-06-29

本文共 4797 字,大约阅读时间需要 15 分钟。

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

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

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

要读取的类文件源码:

 

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
classz=p.getClass();4 System.out.println(classz);5 Person p1=new Person();6 Class
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     }

 


本文为博主原创文章,转载请注明出处:

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

你可能感兴趣的文章
LOJ#6053 简单的函数
查看>>
Python程序输出到文件中
查看>>
C#里WinForm开发中如何实现控件随窗体大小的改变而自动适应其改变(转)
查看>>
sql企业管理器WEB版
查看>>
别再犯低级错误,带你了解更新缓存的四种Desigh Pattern
查看>>
用 Flask 来写个轻博客 (29) — 使用 Flask-Admin 实现后台管理 SQLAlchemy
查看>>
5.2二叉搜索树遍历(前序、中序、后序、层次、广度优先遍历)
查看>>
OAuth 2.0文档翻译(第一章)
查看>>
电梯的测试点
查看>>
限时订单设计
查看>>
wordpress生成xml
查看>>
国外41个精彩的电子商务网站设计欣赏
查看>>
ie8下input文字偏上select文字偏下
查看>>
es6新语法Object.assign()
查看>>
Django 路由、模板和模型系统
查看>>
JAVA递归
查看>>
想要在launcher中模拟按home键。
查看>>
洛谷P3381 最小费用最大流
查看>>
Centos 从零开始 (二)
查看>>
mongodb的用户管理及安全认证
查看>>