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、本博客的目的是知识交流所用,转载自其它博客或网站,作为自己的参考资料的,感谢这些文章的原创人员

posted @ 2016-03-30 09:49  菜鸟奋斗史  阅读(8798)  评论(0编辑  收藏  举报