反射基本介绍&区别&获取Field、Method及Constructor类相关

1.什么是反射

Java 反射(Reflection)是可以让我们在运行时获取类的方法、属性、父类、接口等类的内部信息的机制。也就是说,反射本质上是一个“反着来”的过程。我们通过new创建一个类的实例时,实际上是由Java虚拟机根据这个类的Class对象在运行时构建出来的,而反射是通过一个类的Class对象来获取它的定义信息,从而我们可以访问到它的属性、方法,知道这个类的父类、实现了哪些接口等信息。

反射是一种机制,利用反射机制动态的实例化对象、读写属性、调用方法、构造函数。

2.反射能干什么用

Java Reflection功能非常强大,并且非常有用,比如:

  • 获取任意类的名称、package信息、所有属性、方法、注解、类型、类加载器等

  • 获取任意对象的属性,并且能改变对象的属性

  • 调用任意对象的方法

  • 判断任意一个对象所属的类

  • 实例化任意一个类的对象

  • 通过反射我们可以实现动态装配,降低代码的耦合度,动态代理等。

3.如何使用反射

一切与反射相关的代码都从获取类对应的字节码对象开始。

  • 调用某个类的对象的getClass()方法,

  • 调用类的class属性类获取该类对应的Class对象,

  • 使用Class类中的forName()静态方法,

  • 例如:

        //读写属性、调用方法及构造函数。
        //一切与反射相关的代码都从获取类对象开始
        //1、类名.class
        Class<Student> stuClass = Student.class;
        //2、对象名.getClass
        Student stu =new Student();
        Class<? extends Student> stuClass = stu.getClass();
        //3、Class.forname("类的全路径名")
        Class<?> stuClass = Class.forName("com.zking.entity.Student");
        System.out.println("获取类的全路径名:"+stuClass.getName());
        System.out.println("获取简单类名:"+stuClass.getSimpleName());
        System.out.println("获取包名:"+stuClass.getPackageName());

4.传统实例化与反射实例化区别

  • 传统实例化对象

  • 反射实例化对象

  • 例如:

//3、传统实例化方式与反射实例化方式的区别
        //1、传统
        Student stu =new Student();
        //反射
        //获取类对象
        Class<?> stuClass = Class.forName("com.zking.entity.Student");
        //通过反射机制动态的实例化对象
        Object stu = stuClass.newInstance();

1)Class.forName指定全路径名必须正确,否则将报ClassNotFoundException错误; 2)在运行期间,一个类,类对象只能创建一个

5.反射应用

类名用途
Class类代表类的实体,在运行的Java应用程序中表示类和接口
Field类代表类的成员变量(成员变量也成为类的属性)
Method类代表类的方法
Constructor类代表类的构造函数

5.1.获取Field类相关

类名用途
getField(String name)获取某个公共的属性对象
getFields()获取所有公共的属性对象
getDeclaredField(String name)获取某个属性对象(public和非public)
getDeclaredFields()获取所有属性对象(public和非public)
setAccessible(boolean flag)默认值false,设置true使私有成员允许访问
set(Object,Object)属性赋值
get(Object)获取属性

  • 属性赋值&&获取属性的案例

        //读取属性(Field)
        //获取类对象
        Class<?> stuClass = Class.forName("com.zking.entity.Student");
        //通过反射机制动态的实例化对象
        Object stu = stuClass.newInstance();
        //1)获取公共的单个属性
        Field field = stuClass.getField("sname");
        //2)获取公共的、私有的、受保护的、最终的、静态的等等单个属性
        Field field = stuClass.getDeclaredField("sname");
        //设置权限
        field.setAccessible(true);
        //3)获取所有公共的属性
        Field[] fields = stuClass.getFields();
        //4、获取所有类型的属性
        Field[] fields = stuClass.getDeclaredFields();
        for(Field field : fields){
            System.out.println("属性名:"+field.getName());
            System.out.println("属性类型:"+field.getType());
            System.out.println("访问修饰符:"+field.getModifiers());
           System.out.println("-------------------------");
        }
        //5、属性赋值
        Field field = stuClass.getDeclaredField("sname");
        //参数:1)实例化对象名2)赋的值
        field.setAccessible(true);
        field.set(stu,"man");

注:在对类中私有属性赋值时必须设置访问权限。

5.2.获取Method类相关

类名用途
getMethod(String name, Class<>… parameterTypes)获取该类某个公共的方法
getMethods()获取该类所有公共的方法
getDeclaredMethods(String name,Class<>… parameterTypes)获取该类某个方法(public和非public)
getDeclaredMethod()获取该类所有方法(public和非public)
setAccessible(boolean flag)默认值false,设置true使私有方法允许访问
invoke(Object obj, Object… args)执行方法

  • 调用方法

//5、调用方法(Method)
        //1)获取单个公共的方法
        Method method = stuClass.getMethod("hello");
        //2)获取单个公共的、私有的、受保护的等等方法
        Method method = stuClass.getDeclaredMethod("hello", String.class);
        Method method = stuClass.getDeclaredMethod("add", Integer.class,Integer.class);
        //3)获取所有公共的方法
        Method[] methods = stuClass.getMethods();
        //2)获取所有公共的、私有的、受保护的等等方法
        Method[] methods = stuClass.getDeclaredMethods();
        for (Method method : methods){
            System.out.println("方法名:"+method.getName());
            System.out.println("访问修饰符:"+method.getModifiers());
            System.out.println("返回类型:"+method.getReturnType());
            System.out.println("方法参数数量:"+method.getParameterCount());
            System.out.println("------------------------");
        }

        //5、调用方法
        Method method = stuClass.getMethod("hello");
        Method method = stuClass.getDeclaredMethod("add", Integer.class,Integer.class);
        method.setAccessible(true);
        //调用方法
        //参数1:实例化对象名
        //参数2:方法本身所需参数(可变参数)
        Object returnValue = method.invoke(stu,1,5);
        System.out.println(returnValue);

5.3.获取Constructor类相关

类名用途
getConstructor(Class<>… parameterTypes)获取该类中与参数类型匹配的公有构造方法
getConstructors()获取该类的所有公共构造方法
getDeclaredConstructors(Class<>… parameterTypes)获取该类中与参数类型匹配的构造方法
getDeclaredConstructors()获取该类所有构造方法(public和非public)
  •  调用方法
//        Constructor构造函数的相关案例
//        1)获取单个公共的构造函数
        Constructor<?> constructor = stuClass.getConstructor();
//        2)获取单个公共的、私有的等等构造函数
        Constructor<?> constructor = stuClass.getDeclaredConstructor(String.class);
//        3)获取所有公共的构造函数
        Constructor<?>[] constructors = stuClass.getConstructors();
        for (Constructor constructor : constructors){
            System.out.println("方法名:"+constructor.getName());
            System.out.println("访问修饰符:"+constructor.getModifiers());
            System.out.println("参数数量:"+constructor.getParameterCount());
            System.out.println("---------------------");
        }
//        4)获取所有公共的、私有的等等构造函数
        Constructor<?>[] constructors = stuClass.getDeclaredConstructors();
        for (Constructor constructor : constructors){
            System.out.println("方法名:"+constructor.getName());
            System.out.println("访问修饰符:"+constructor.getModifiers());
            System.out.println("参数数量:"+constructor.getParameterCount());
            System.out.println("---------------------");
        }

//        5)通过构造函数实例化对象
        Constructor<?> constructor = stuClass.getConstructor();
        Object newInstance = constructor.newInstance();

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值