java 反射的基本用法

一、什么是反射

反射首先是能够获取到Java中的反射类的字节码,然后将字节码中的方法,变量,构造函数等映射成 相应的 Method、Filed、Constructor 等类

二、反射的API
获取class字节码对象 的3 种方法

   //第一种 
   Class studentClass = Student.class;
   //第二种
  Student student = new Student();
  Class studentClass1 = student.getClass();
  //第三种 必须为全路径
 Class studentClass2 = Class.forName("com.example.service.Impl.Student");

常用的一些API

获取包名 类名
clazz.getPackage().getName()//包名
clazz.getSimpleName()//类名
clazz.getName()//完整类名

获取成员变量定义信息
getFields()//获取所有公开的成员变量,包括继承变量
getDeclaredFields()//获取本类定义的成员变量,包括私有,但不包括继承的变量
getField(变量名)
getDeclaredField(变量名)

获取构造方法定义信息
getConstructor(参数类型列表)//获取公开的构造方法
getConstructors()//获取所有的公开的构造方法
getDeclaredConstructors()//获取所有的构造方法,包括私有
getDeclaredConstructor(int.class,String.class)

获取方法定义信息
getMethods()//获取所有可见的方法,包括继承的方法
getMethod(方法名,参数类型列表)
getDeclaredMethods()//获取本类定义的的方法,包括私有,不包括继承的方法
getDeclaredMethod(方法名,int.class,String.class)

反射新建实例
clazz.newInstance();//执行无参构造创建对象
clazz.newInstance(666,”海绵宝宝”);//执行含参构造创建对象
clazz.getConstructor(int.class,String.class)//获取构造方法

反射调用成员变量
clazz.getDeclaredField(变量名);//获取变量
clazz.setAccessible(true);//使私有成员允许访问
f.set(实例,值);//为指定实例的变量赋值,静态变量,第一参数给null
f.get(实例);//访问指定实例变量的值,静态变量,第一参数给null

反射调用成员方法
Method m = Clazz.getDeclaredMethod(方法名,参数类型列表);
m.setAccessible(true);//使私有方法允许被调用
m.invoke(实例,参数数据);//让指定实例来执行该方法

三、示例

首先定义一个类

@Data
@Builder
@Service
public class Student {

    public String name;

    private int age;

    public char egx;

    protected Integer phone;

    Student(String name ,int age,char egx,Integer phone){
        System.out.println("默认的构造方法");
    }
    public Student(){
        System.out.println("调用无参构造方法。。。。。");
    }

    public  Student(String name){
        this.name = name;
        System.out.println("name:"+name);
    }

    public Student(String name,int age){
        System.out.println("name:"+name+","+"age:"+age);
    }

    private Student(int age){
        System.out.println("私有的构造方法");
    }

    protected Student(boolean b){
        System.out.println("受保护的构造方法");
    }

    public String get(){
        return "调用方法";
    }

    public String getMethod(String string){
        return string + "是个大学老师!";
    }
}

获取构造方法

/*
 * 通过Class对象可以获取某个类中的:构造方法、成员变量、成员方法;并访问成员;
 *
 * 1.获取构造方法:
 * 		1).批量的方法:
 * 			public Constructor[] getConstructors():所有"公有的"构造方法
            public Constructor[] getDeclaredConstructors():获取所有的构造方法(包括私有、受保护、默认、公有)

 * 		2).获取单个的方法,并调用:
 * 			public Constructor getConstructor(Class... parameterTypes):获取单个的"公有的"构造方法:
 * 			public Constructor getDeclaredConstructor(Class... parameterTypes):获取"某个构造方法"可以是私有的,或受保护、默认、公有;
 *
 * 			调用构造方法:
 * 			Constructor-->newInstance(Object... initargs)
 */

    System.out.println("==================调用构造方法=====================");
    Class clazz = Student.class;
    //类路径
    System.out.println(clazz.getName());
    //获取所有的公共构造方法
   Constructor[] constructors = clazz.getConstructors();
    for (Constructor constructor : constructors){
        System.out.println(constructor);
    }
    //获取所有的构造方法 包含私有的受保护的
    Constructor[] declaredConstructors = clazz.getDeclaredConstructors();
    for (Constructor constructor : declaredConstructors){
        System.out.println(constructor);
    }
    //获取 公共的参数为String的构造方法
    Constructor constructor = clazz.getConstructor(String.class);
    System.out.println(constructor);

    //获取公共的无参构造方法
    Constructor constructor1 = clazz.getConstructor(null);
    System.out.println(constructor1);
    Object o = constructor1.newInstance();

    Constructor declaredConstructor = clazz.getDeclaredConstructor(String.class);
    //暴力访问,忽略掉访问修饰符
    declaredConstructor.setAccessible(true);
    Object object = declaredConstructor.newInstance("男");

获取成员变量并调用:

/*
     * 获取成员变量并调用:
     *
     * 1.批量的
     * 		1).Field[] getFields():获取所有的"公有字段"
     * 		2).Field[] getDeclaredFields():获取所有字段,包括:私有、受保护、默认、公有;
     * 2.获取单个的:
     * 		1).public Field getField(String fieldName):获取某个"公有的"字段;
     * 		2).public Field getDeclaredField(String fieldName):获取某个字段(可以是私有的)
     *
     * 	 设置字段的值:
     * 		Field --> public void set(Object obj,Object value):
     * 					参数说明:
     * 					1.obj:要设置的字段所在的对象;
     * 					2.value:要为字段设置的值;
     *
     */
     
     
        System.out.println("=====================获取字段参数=====================");
          Class clazz = Class.forName("com.example.service.Impl.Student");;
        //获取所有公共参数
        Field[] fields = clazz.getFields();
        for(Field field : fields){
            // System.out.println(field);
        }

        //获取所有参数
        Field[] declaredFields = clazz.getDeclaredFields();
        for (Field field : declaredFields){
            System.out.println(field);
        }


        //获取 name 参数
        Field name = clazz.getField("name");
        // Student s = new Student();
        Object o = clazz.getConstructor(null).newInstance();
        //给name 参数 赋值
        name.set(o,"黄磊");
        Student s = (Student)o;
        System.out.println("验证名字:"+s.getName());
        //获取私有参数
        Field phone = clazz.getDeclaredField("phone");
        //暴力访问,忽略掉访问修饰符
        phone.setAccessible(true);
        //第一个参数为设置的对象,第二个参数为要传入的实参
        //等同与student.setPhone(12356789)
        phone.set(o,123456789);
        System.out.println("验证电话:"+s.getPhone());

获取方法并调用

     System.out.println("=====================获取方法=======================");
        Class clazz = Student.class;
        //获取所有公共的方法
        Method[] methods = clazz.getMethods();
        //获取所以方法 包含私有的,受保护的
        Method[] declaredMethods = clazz.getDeclaredMethods();
        for (Method method : declaredMethods){
            System.out.println(method.getName());
        }
        Method getMethod = clazz.getMethod("getMethod",String.class);
        //无参初始化
        Object o1 = clazz.newInstance();
        //执行方法为私有的 得先设置私有可见
        getMethod.setAccessible(true);
        //传入参数,执行方法
        Object o = getMethod.invoke(o1,"ww");
        System.out.println(o.toString());
  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值