java 之 反射 (结合Class理解)

反射机制使静态语言java变为准动态语言

Reflection 反射机制允许程序在执行期借助于Reflection API取得任何类的内部信息,并能直接操作任意对象的内部属性及方法

反射方式 实例化对象--》getClass()方法--》得到完整的“包类”名称

类加载完之后,堆内存中产生一个class型对象。(一个类只能有一个Class对象),这个对象中包含了完整的类的结构信息。一个类被加载之后,所有类结构都会被封装到class对象中

反射相关的主要API

  • java.lang.Class 代表一个类
  • java.lang.reflect.Method 代表类的方法
  • java.lang.reflect.Field 代表类的成员变量
  • java.lang.reflect.Constructor 代表类的构造器

通过反射可以获取类的包名,全类名

  • class.getName()
  • class.getSimpleName()

可以获得类的属性

  • .getFields() 获得的都是类中的非私有属性
  • .getDeclaredFields() 获得全部的属性 
  • 以上加参数可以获得指定属性,比如.getFields("name")

可以获得类的方法

  • .getMethods()  非私有方法
  • .getDeclaredMethods() 全部方法
  • 也可以获得指定方法如 class.getMethods("getName",null) 
  • 如果有重载方法的话后面给出指定参数 如class.getMethods("getName",String.class) int.class等

可以获得指定的构造器

  • .getConstructors()
  • .getDeclaredConstructors()

可以通过调用class对象的newInstance()方法

  • 类必须有无参构造器
  • 类的构造器的访问权限需要足够

还可以通过构造器创建对象

  1. 首先获取到对应的构造器。
  2. 用对应的构造器的newInstance创建一个对象

调用指定的方法

通过反射,调用类中的方法,通过Method类完成

  1. 通过getMethod(String name,Class parameterType ) 获取到一个Method对象。并设置此方法需要的参数类型。
  2. 使用 Object invoke(Object obj,Object args),并向方法中传递设置的obj对象的参数信息。

简单来说就是获得通过方法获得方法之后,通过invoke激活一下

直接上例子

package com.company;

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

/**
 * @Author:XK
 * @Date: Created in 17:25 2021/10/25
 * @Description: 测试反射调用一个方法
 **/
public class Test03 {
    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {
        Class c1 = Class.forName("com.company.User");

        //构造一个对象
        User user = (User) c1.newInstance();
        System.out.println(user);

        //通过构造器来构造一个对象
        Constructor constructor = c1.getDeclaredConstructor(int.class);
        User user2 = (User) constructor.newInstance(12);
        System.out.println(user2);

        //通过反射调用普通方法
         User user3 = (User) c1.newInstance();
        Method setName = c1.getMethod("setName", String.class);
        setName.invoke(user3,"kakaka");
        System.out.println(user3.getName());

        //通过反射操作属性
        System.out.println("=======================");
        User user4 =(User) c1.newInstance();
        Field name = c1.getDeclaredField("name");

        //设置私有name是可接近的,关闭代码的安全检测
        name.setAccessible(true);
        name.set(user4,"xkkk2");
        System.out.println(user4.getName());
    }
}

 setAccessible

Method Field Constructor 都是有这个方法的,作用是启动和禁止访问安全检查的开关。

true为反射的对象在使用时取消访问检查 false则实施访问检查

如果代码中频繁使用反射,设置为true。使得原本无法访问的私有成员也可以访问。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值