JAVA反射机制【超详细!!】

JAVA反射机制

反射的概述

JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。

反射就是把java类中的各种成分映射成一个个的Java对象

例如:一个类有:成员变量、方法、构造方法、包等等信息,利用反射技术可以对一个类进行解剖,把个个组成部分映射成一个个对象。

反射的用途

当我们在使用IDEA时,当我们输入一个对象或者类,并想调用他的属性和方法是,一按点号,编译器就会自动列出他的属性或者方法,这里就是用到反射。

反射的基本使用:

要使用反射,首先要获取类的Class对象。

获得字节码文件对象:主要有三种方法:

  • 对象.getClass()

  • 任何数据类型(包括基本的数据类型)都有一个“静态”的class属性 类.class

  • 通过class类的静态方法:forName(String className)(最常用)

package myreflectDemo1;

public class MyReflectDemo {
    public static void main(String[] args) throws ClassNotFoundException{

        //第一种 对象.getClass()
        Student student = new Student();
        Class class1 = student.getClass();
        System.out.println(class1);

        //第二种 类名.class
        Class<Student> class2 = Student.class;
        System.out.println(class2);
        //第三种 Class.forName("全类名")
        Class class3 = Class.forName("myreflectDemo1.Student");
        System.out.println(class3);

        //指向同一个地址 都是Student这个类
        System.out.println(class1 == class2);
        System.out.println(class2 == class3);

    }
}

三种方式中,常用第三种,第一种对象都有了还要反射干什么,第二种需要导入类包,依赖太强,不导包就抛编译错误。一般都使用第三种,一个字符串可以传入也可以写在配置文件中等多种方法。

通过反射获取构造方法并使用:

 //        Class类中用于获取当前类构造方法的方法
 //        Constructor[] getConstructors             所有公共的构造方法
 //        Constructor[] getDeclaredConstructors     所有构造方法
 //        Constructor getConstructor                单个公共的构造方法  (只能是公共的)
 //        Constructor getDeclaredConstructor        单个构造方法
package myreflectDemo2;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

public class MyReflectDemo {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {

        //访问构造方法  Constructor

        Class class1 = Class.forName("myreflectDemo2.Student");
        //获取当前类class字节码文件对象
        System.out.println("当前类====="+class1);

//        Class类中用于获取当前类构造方法的方法
//        Constructor[] getConstructors             所有公共的构造方法
//        Constructor[] getDeclaredConstructors     所有构造方法
//        Constructor getConstructor                单个公共的构造方法  (只能是公共的)
//        Constructor getDeclaredConstructor        单个构造方法

        //无参和一个参数的构造方法是私有的,两个参数和全参的构造方法是公共的
        System.out.println("--------所有公共的构造方法----------");
        Constructor[] constructors1 = class1.getConstructors();
        for(Constructor con:constructors1){
            System.out.println(con);
        }

        System.out.println("--------所有构造方法----------");
        Constructor[] constructors2 = class1.getDeclaredConstructors();
        for(Constructor con:constructors2){
            System.out.println(con);
        }

        System.out.println("--------单个公共的构造方法----------");
        //空参构造方法是私有的,会报错
//        System.out.println(class1.getConstructor());
        Constructor constructor3 = class1.getConstructor(String.class, int.class);
        System.out.println(constructor3);

        System.out.println("--------单个构造方法----------");
        Constructor constructor4 = class1.getDeclaredConstructor();
        System.out.println(constructor4);


        System.out.println("--------获取构造方法的访问修饰符----------");
        //访问修饰符为1   公共的
        //访问修饰符为2   私有的
        int modifiers1 = constructor3.getModifiers();
        int modifiers2 = constructor4.getModifiers();
        System.out.println("两个参数的构造方法====="+modifiers1);
        System.out.println("无参的构造方法====="+modifiers2);


        System.out.println("--------获取构造方法的参数的个数----------");
        int parameterCount1 = constructor3.getParameterCount();
        int parameterCount2 = constructor4.getParameterCount();
        System.out.println("两个参数的构造方法的参数个数====="+parameterCount1);
        System.out.println("无参的构造方法的参数个数====="+parameterCount2);


        System.out.println("--------获取构造方法创建对象----------");
        Student student1 = (Student)constructor3.newInstance("张三", 18);

        constructor4.setAccessible(true);        // 暴力反射  表示临时取消权限校验
        Student student2 = (Student)constructor4.newInstance();
        System.out.println("两个参数的构造方法=========="+student1);
        System.out.println("无参的构造方法=========="+student2);
    }
}

通过反射获取成员变量并使用:

 //访问成员变量 Field
 ​
 //        Field[] getFields()         获取所有公共的成员变量
 //        Field[] getDeclaredFields() 获取所有公成语变量
 //        Field getField(String name)            获取单个公共的成员变量
 //        Field getDeclaredField (String name)   获取单个成员变量
package myreflectDemo3;

import java.lang.reflect.Field;

public class MyReflectDemo {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException {

        //访问成员变量 Field

//        Field[] getFields()         获取所有公共的成员变量
//        Field[] getDeclaredFields() 获取所有公成语变量
//        Field getField(String name)            获取单个公共的成员变量
//        Field getDeclaredField (String name)   获取单个成员变量

        //获取字节码class文件的对象
        Class class1 = Class.forName("myreflectDemo3.Student");
        System.out.println("--------所有公共的成员变量----------");
        Field[] fields = class1.getFields();
        for (Field field:fields){
            System.out.println(field);
        }

        System.out.println("--------所有成员变量----------");
        Field[] fieldss = class1.getDeclaredFields();
        for (Field field:fieldss){
            System.out.println(field);
        }

        System.out.println("--------单个公共的成员变量----------");
        Field field1 = class1.getField("name");
        System.out.println(field1);



        System.out.println("--------单个成员变量----------");
        Field field2 = class1.getDeclaredField("age");
        System.out.println(field2);

        //获取访问修饰符  getModifiers
        //访问修饰符为1   公共的
        //访问修饰符为2   私有的
        System.out.println("--------成员变量的访问修饰符类别----------");
        int modifiers1 = field1.getModifiers();
        int modifiers2 = field2.getModifiers();
        System.out.println("name访问修饰符======"+modifiers1);
        System.out.println("age访问修饰符======"+modifiers2);


        System.out.println("--------成员变量的数据类型----------");
        Class<?> type1 = field1.getType();
        Class<?> type2 = field2.getType();
        System.out.println("name的数据类型======"+type1);
        System.out.println("age的数据类型======"+type2);

        System.out.println("--------获取成员变量的值----------"); //field1  name的值
        Student student = new Student("张三",18);
        String s = (String) field1.get(student);
        System.out.println("name的值==="+s);

        //用反射修改对象成员变量的值   field1  name的值 "张三"-->"李四"
        System.out.println("--------修改成员变量的值----------");
        field1.set(student,"李四");
        System.out.println("name的值==="+student.name);
    }


}

通过反射获取构成员方法并使用

         //访问成员方法 Method
 ​
 //        Method[] getMethods()         获取所有公共的成员方法
 //        Method[] getDeclaredMethods() 获取所有公成语成员方法
 //        Method getMethod(形参列表)  获取单个公共的成语成员方法
 //        Method getMethod (形参列表)   获取单个成语成员方法
package myreflectDemo4;


import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class MyReflectDemo {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        //访问成员方法 Method

//        Method[] getMethods()         获取所有公共的成员方法
//        Method[] getDeclaredMethods() 获取所有公成语成员方法
//        Method getMethod(形参列表)  获取单个公共的成语成员方法
//        Method getMethod (形参列表)   获取单个成语成员方法

        Class<?> class1 = Class.forName("myreflectDemo4.Student");

        //getMethods() 获取所有公共的成员方法(包含父类的所有公共的成员方法)
        System.out.println("--------所有公共的成员方法----------");
        Method[] methods = class1.getMethods();
        for (Method method : methods) {
            System.out.println(method);
        }

        //getDeclaredMethods()  获取所有成员方法(不能获取父类的,只能获取本类所有的包含私有的成员方法)
        System.out.println("--------所有成员方法----------");
        Method[] declaredMethods = class1.getDeclaredMethods();
        for (Method declaredMethod : declaredMethods) {
            System.out.println(declaredMethod);
        }

        System.out.println("--------单个公共的成员方法----------");
        Method sleep = class1.getMethod("sleep");
        Method setAge = class1.getMethod("setAge",int.class);
        System.out.println("sleep()方法==="+sleep);
        System.out.println("setAge()方法==="+setAge);

        System.out.println("--------单个成员方法----------");
        Method eat = class1.getDeclaredMethod("eat");
        System.out.println("eat()方法==="+eat);

        //获取方法的访问修饰符  getModifiers
        //访问修饰符为1   公共的
        //访问修饰符为2   私有的
        System.out.println("--------成员方法访问修饰符----------");
        int modifiers = sleep.getModifiers();
        int modifiers1 = eat.getModifiers();
        System.out.println("sleep()方法访问修饰符==="+modifiers);
        System.out.println("eat()方法访问修饰符==="+modifiers1);

        //获取方法的参数个数  getParameterCount()
        System.out.println("--------成员方法参数个数---------");
        int parameterCount = setAge.getParameterCount();
        System.out.println("setAge()方法参数个数==="+parameterCount);

        //获取方法抛出的异常   getExceptionTypes()
        System.out.println("--------成员方法抛出的异常---------");
        System.out.println("sleep方法抛出的异常");
        Class<?>[] exceptionTypes = sleep.getExceptionTypes();
        for (Class<?> exceptionType : exceptionTypes) {
            System.out.println(exceptionType);
        }

        System.out.println("--------成员方法的返回值---------");
        Student student = new Student();
        Method write = class1.getMethod("write", String.class);
        //invoke  第一个参数表示方法的调用者  第二个参数表示传的参数  返回值就是成员方法的返回值
        String invoke = (String) write.invoke(student, "张三");
        System.out.println(invoke);


    }
}

  • 7
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值