Java反射机制与动态代理(一)

来源:互联网 发布:vb眼镜正品多少钱 编辑:程序博客网 时间:2024/05/30 07:12

导读:
1. 什么是反射
2. 反射的基本使用
3. 反射的使用实例

一、什么是反射?

  Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。简而言之,通过反射,我们可以在运行时获得程序或程序集中每一个类型的成员和成员的信息。

反射机制是Java语言的一个重要特性,它允许用户动态获取类的信息和动态调用对象的方法。它提供的类及对应的功能如下:

  • Class类:代表一个Java类。
  • Field类:代表Java类的属性。
  • Method类:代表Java类的方法。
  • Constructor类:代表Java类的构造函数。
  • Array类:提供了动态创建数组,以及访问数组元素的静态方法。
  • Proxy类以及InvocationHandler接口:提供了动态生成代理类以及实例的方法。

注意:反射的核心是JVM在运行时才动态加载类或调用方法/访问属性,它不需要事先知道运行对象是谁。

二、反射的基本使用

1、获取Class对象

方法有三种
(1)直接获取某一个对象的class

Class<?> c = A.class;

(2)使用Class类的forName静态方法

Class<?> c = Class.forName("walker.reflect.A");

(3)通过某个对象的getClass()方法获得

Class<?> c = new A().getClass();
//获得类的完整名字System.out.println("类名:" + c.getName());//获得类加载器。默认类加载器是sun.misc.Launcher$AppClassLoaderSystem.out.println("类加载器:" + c.getClassLoader().getClass().getName());
2、反射创建实例

通过反射来创建对象主要有两种。
(1)使用Class对象的newInstance()方法来创建Class对象对应类的实例

Class<?> c = new A().getClass();t.newInstance();  //根据默认的构造器创建实例

(2)先通过Class对象获取指定对象的Constructor对象,在调用Constructor对象的newInstance()方法来创建实例。

Class<?> c = new A().getClass();//获取A的带一个String参数构造器Constructor<?> constructor = c.getConstructor(new Class<?>[]{java.lang.String.class});//根据指定的构造器创建实例 Object obj = constructor.newInstance("arg"); 
3、获取类中声明的属性,并通过反射修改声明的属性
//获得当前类和父类中的public类型的所有属性Field[] publicField = c.getFields();
// 获得当前类(不包含父类)声明的所有属性,包括private和publicField[] declareFields = c.getDeclaredFields();
//根据名称获取指定属性Field specifyField = c.getField("age");
//使用反射修改声明属性specifyField.setAccessible(true);specifyField.set(newObj, 88);
4、获取类的方法,并通过反射调用对象的方法
//获得当前类和父类中public类型的所有方法Method[] publicMethods = c.getMethods();
//获得当前类(不包含父类)声明的所有方法,包括public和privateMethod[] declareMethods = c.getDeclaredMethods();
//根据方法名和方法参数类型指定获取一个方法Method specifyMethod = c.getDeclaredMethod("func1", new Class<?>[]{java.lang.String.class});
//使用反射调用对象的方法specifyMethod.invoke(newObj, "I am reflect method.");
5、获得继承的父类和实现的接口
//获得继承的父类Class<?> superclass = c.getSuperclass();
//获得实现的接口Class<?>[] interfaces = c.getInterfaces();

三、Java反射使用实例

package walker.reflect;import java.lang.reflect.Constructor;import java.lang.reflect.Field;import java.lang.reflect.Method;public class ReflectDemo {    public static void main(String[] args) throws Exception {        /*         * 1-获得类Class对象         */        //(1-1)直接获取某一个对象的class        Class<?> class2 = A.class;        //(1-2)使用Class类的forName静态方法        Class<?> demoClass = Class.forName("walker.reflect.A");        //(1-3)通过某个对象的getClass()方法获得        Class<?> class3 = new A().getClass();        //获得类的完整名字        System.out.println("类名:" + demoClass.getName());        //获得类加载器。默认类加载器是sun.misc.Launcher$AppClassLoader        System.out.println("类加载器:" + demoClass.getClassLoader().getClass().getName());        /*         * 2-通过反射创建实例         */        //(2-1)使用Class对象的newInstance()方法来创建Class对象对应类的实例        A newObj = (A) demoClass.newInstance();        //(2-2)先通过Class对象获取指定对象的Constructor对象,在调用Constructor对象的newInstance()方法来创建实例。        //获取A的带一个String参数构造器        Constructor<?> constructor = demoClass.getConstructor(new Class<?>[]{java.lang.String.class});        //根据构造器创建实例        Object obj = constructor.newInstance("walker");        /*         * 3-获得类中声明的属性,并通过反射修改声明的属性         */        //获得当前类和父类中的public类型的所有属性        Field[] publicField = demoClass.getFields();        // 获得当前类(不包含父类)声明的所有属性,包括private和public        Field[] declareFields = demoClass.getDeclaredFields();        //根据名称获取指定属性        Field specifyField = demoClass.getField("age");        //使用反射修改声明属性        specifyField.setAccessible(true);        specifyField.set(newObj, 88);        /*         * 4-获得类的方法,并通过反射调用对象的方法         */        //获得当前类和父类中public类型的所有方法        Method[] publicMethods = demoClass.getMethods();        //获得当前类(不包含父类)声明的所有方法,包括public和private        Method[] declareMethods = demoClass.getDeclaredMethods();        //根据方法名和方法参数类型指定获取一个方法        Method specifyMethod = demoClass.getDeclaredMethod("func1", new Class<?>[]{java.lang.String.class});        //使用反射调用对象的方法        specifyMethod.invoke(newObj, "I am reflect method.");        /*         * 5-获得继承的父类及实现的接口         */        //获得继承的父类        Class<?> superclass = demoClass.getSuperclass();        //获得实现的接口        Class<?>[] interfaces = demoClass.getInterfaces();    }}class B {    public int b;    public B() {}}interface IA {}class A extends B implements IA {    public A() {}    public A(String str){ }    public A(String str1, String str2) { }    private String str;    public int age;    public int func1(String name) {        System.out.println("hello " + name);        return 0;    }    public int func1(String name1, String name2) {        System.out.println("hello " + name1 +"," + name2);        return 0;    }}

【参考资料】

[1] sczyh30, 深入解析Java反射(1) - 基础。http://www.sczyh30.com/posts/Java/java-reflection-1/
[2] hduhans, Java反射与动态代理。 http://www.cnblogs.com/hanganglin/p/4485999.html

原创粉丝点击