Java反射机制总结一

来源:互联网 发布:蓝光播放器网络排名 编辑:程序博客网 时间:2024/05/19 13:42

java反射机制

java的反射机制是指在运行状态中,对于任意一个类,可以获取它的属性和方法,对于任意一个对象,可以调用它的任意方法或者属性,这种在运行状态下动态获取程序信息和调用的机制称为java的反射机制。

动态语言:程序在运行的时候,允许改变程序的数据结构和变量类型,称之为动态语言。java的反射机制是java被称之为动态语言的关键。

反射的大体流程:
正常的方式:引入需要的“包类”名称->使用new关键字创建对象->获取实例化的对象。
反射:实例化的对象->getClass方法获取运行时类(Class对象)->得到“包类”名称,执行方法,获取属性,动态创建对象等。

说到底java反射可以做的事情就是:

  1. 在运行的时候判断任意一个对象所属的类。
  2. 在运行的时候构造任意一个类的对象。
  3. 在运行的时候获取一个类的所有成员变量和方法。
  4. 在运行的时候调用任意一个对象的成员变量和方法。
  5. 生成动态代理。

主要的API包括:

java.lang.Class 代表一个类java.lang.reflect.Methoad, 代表类中方法java.lang.reflect.Field 代表类的属性(成员变量)java.lang.reflect.Constructor 代表类的构造方法

Class类

Class类就是运行时类, 在java中,每个class都有一个对应的class对象,也就是说,每一个.java文件编译完成,其中的类都会生成Class对象, 用来表示这个类的完整结构。也就是说,Class类反射的源头。

Class对象不能认为创建,由jvm负责创建。在运行时,当需要创建某个类的实例的时候,jvm就会检查该类的Class对象是否已经被加载
如果没有加载就会根据类名找到对应的.class文件并且加载它,然后就可以:

        1. 创建运行时类对应的对象。        2. 获取运行时类的完整结构(属性,方法构造器,内部类,父类,包名,注解等)。        3. 调用运行时类指定的结构(属性,方法,构造器)。        4. 反射的应用,动态代理

获取Class类的方法

  1. 调用运行时类本身的class属性。例如:String.classs。
  2. 通过运行时类的对象获取(getClass方法)。例如:Person p = new Person(); Class clazz = p.getClass();
  3. 通过Class类的静态方法Class.forName(); 例如:Class.forName(“com.mysql.jdbc.Driver”);
  4. 通过类加载器获取Class对象
// 四种方式获取Class对象    @Test    public void test6() throws Exception {        // 1.调用运行时类本身的class属性。        System.out.println(String.class);        System.out.println(Person.class);        // 2.通过运行时类的对象获取(getClass方法)。        Person p = new Person();        System.out.println(p.getClass());        // 3.通过Class类的静态方法Class.forName()。        Class clazz = Class.forName("com.tuxianchao.Person");        System.out.println(clazz);        // 4.通过类加载器获取Class对象        ClassLoader classLoader = this.getClass().getClassLoader();        Class clazz1 = classLoader.loadClass("com.tuxianchao.Person");        System.out.println(clazz1);    }

这里写图片描述

Class类的常用方法

Class类的常用方法
1. getName() 获取全类名(getSimpleName()获取类名)
2. newInstance() 创建一个该Class对应的对象
3. getClassLoader() 获取该类的类加载器
4. getSuperClass() 获取父类的Class

反射的应用

反射获取类的属性和方法

// 使用反射获取类的属性和方法    @Test    public void test2() throws Exception {        // 创建运行时类的Class对象        Class<Person> clazz = Person.class;        // 获取所有属性        Field field[] = clazz.getDeclaredFields();        for (int i = 0; i < field.length; i++) {            System.out.println(field[i]);        }        System.out.println();        // 获取所有方法        Method method[] = clazz.getDeclaredMethods();        for (int i = 0; i < method.length; i++) {            System.out.println(method[i]);        }    }

这里写图片描述

反射创建对象

// 使用反射构造一个对象    @Test    public void test3() throws Exception {        Class<Person> clazz = Person.class;        Person p = clazz.newInstance();// 反射创建对象        System.out.println(p);        // 当使用带参构造器创建对象的时候,newInstance方法就能满足需求了,需要使用构造器来创建对象        Constructor<Person> constructor = clazz.getConstructor();        Person p1 = constructor.newInstance();        Constructor<Person> constructor1 = clazz.getConstructor(String.class);        Person p2 = constructor1.newInstance("Li");        Constructor<Person> constructor2 = clazz.getConstructor(String.class, int.class);        Person p3 = constructor2.newInstance("Zhang", 20);        System.out.println(p1);        System.out.println(p2);        System.out.println(p3);    }

这里写图片描述

反射调用方法或者属性

// 使用反射调用属性或者方法    @Test    public void test4() throws Exception {        Class<Person> clazz = Person.class;        Person p = clazz.newInstance();        Field f1 = clazz.getDeclaredField("name");        // 调用属性        f1.setAccessible(true);// 设置禁用访问权限        f1.set(p, "Li");// 设置属性        System.out.println(f1.get(p));// 获取属性        System.out.println(p);        /*         * 调用方法 getDeclaredMethod方法,传入方法的名字和参数类型(class)来确定哪一个方法         * invoke执行方法的时候传入参数         */        Method m1 = clazz.getDeclaredMethod("setAge", int.class);        m1.setAccessible(true);        m1.invoke(p, 20);        System.out.println(p);    }

这里写图片描述

使用反射来在运行的时候判断任意一个对象所属的类。

// 使用反射来在运行的时候判断任意一个对象所属的类。    @Test    public void test5() throws Exception {        Person p = new Person();        // getClass返回运行类        System.out.println(p.getClass().getName());        System.out.println(p.getClass().getSimpleName());    }

这里写图片描述

0 0
原创粉丝点击