java中的反射基本用法

反射

反射允许对成员变量,成员方法和构造方法的编程访问

IDEA中的形参提示,方法列出,都是利用反射实现的。

即:反射可以从类中,获取成员变量,成员方法,构造方法。

获取class对象 : Class

构造方法: Constructor

字段(成员变量): Field

成员方法: Method

样例Student类:

package MyReflectDemo1;

public class Student {
    private String name;
    private int age;
    public String gender;

    public Student(){

    }

    public Student(String name, int age ,String gender) {
        this.name = name;
        this.age = age;
        this.gender=gender;
    }
    private Student(String name){
        this.name = name;
    }
    protected  Student(int age){
        this.age = age;
    }

    public String getName() {

        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
    public void setGender(String gender){
        this.gender=gender;
    }

    public String getGender(){

        return gender;
    }

    public void study() {
        System.out.println(name + "正在学习");
    }
    
    private void play(){
        System.out.println("正在部署爆能器");
    }
    
    protected void sleep(){
        System.out.println("正在睡觉");
    }
    
    public String eat(String food) throws NullPointerException{
        System.out.println("在吃" + food);
        return "吃饱辣";
    }
    
    public void eat(String food, String water) {
        
        System.out.println("在吃" + food + "喝" + water);
    }

}

获取class对象的三种方式

public class MyReflectDemo1 {
    public static void main(String[] args) throws ClassNotFoundException {
        //Class.forName(全类名)方法获取class文件,全类名:包名+类名
        Class clazz1 = Class.forName("MyReflectDemo1.Student");//最常用
        System.out.println(clazz1);

        //类名.class
         Class clazz2 = Student.class;//常作为参数使用
        // 如 : synchronized (clazz2)

         //对象.getClass()
        //当已经有了这个类的对象时,才可以使用
         Student s = new Student();
         Class clazz3 = s.getClass();
         System.out.println(clazz3 == clazz1);
         System.out.println(clazz3 == clazz1);
         //获取到的class对象是同一个
    }
}

反射获取构造方法

public class MyReflectDemo1 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException {
        Class clazz1 = Class.forName("MyReflectDemo1.Student");

         //获取到的class对象是同一个

        //获取构造方法(需获取class字节码文件)
        Constructor[] cons = clazz1.getConstructors();//获取所有公有的构造方法
        for(Constructor con : cons)
        {
            System.out.println(con);
        }

        //获取所有构造方法(包括公有,私有,保护)
        Constructor[] declaredConstructors = clazz1.getDeclaredConstructors();
        for (Constructor declaredConstructor : declaredConstructors) {
            System.out.println(declaredConstructor);
        }

        Constructor con = clazz1.getDeclaredConstructor();//获取空参的一个构造方法
        System.out.println(con);

        Constructor con1 = clazz1.getDeclaredConstructor(String.class, int.class);//获取有参的构造方法
        System.out.println(con1);
    
        Constructor constructor = clazz1.getConstructor();//获取空参的一个公有构造方法
        System.out.println(constructor);
        
        Constructor constructor1 = clazz1.getConstructor(String.class, int.class);//获取有参的公有构造方法
        System.out.println(constructor1);
        
        //获取构造方法的修饰符
        int modifiers = constructor1.getModifiers();
        System.out.println(modifiers);
        
        //获取构造方法的参数
        Parameter[] parameters = con1.getParameters();
        for (Parameter parameter : parameters) {
            System.out.println(parameter);
        }
        
        //暴力反射
        //利用反射强行调用私有方法创建对象(即自动装配原理,底层暴力反射)
        con1.setAccessible(true);//临时取消权限校验:获取构造方法只是显现,依然无法直接访问,需要取消权限校验
        Student  yg = (Student) con1.newInstance("杨光", 19);
        System.out.println(yg);
    }
}

getModifiers()方法可以获取修饰符,但不是以字符串形式展现,是以整数类型展现。

abstract : 1024 Final: 16 interface: 512 private : 2

public: 1 static: 8 等等

反射获取成员变量

public class MyReflectDemo2 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException {
        Class clazz = Class.forName("MyReflectDemo1.Student");

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

        System.out.println("----------------芝士分割线------------------");

        //获取所有公共成员变量
        Field[] fields = clazz.getFields();
        for(Field field : fields){
            System.out.println(field);
        }

        System.out.println("----------------芝士分割线------------------");

        //获取指定成员变量(公共修饰符)
        Field gender1 = clazz.getField("gender");
        System.out.println(gender1);

        //获取指定成员变量(所有修饰符)
        Field name = clazz.getDeclaredField("name");
        System.out.println(name);

        //获取成员变量的修饰符
        int modifiers = name.getModifiers();
        System.out.println(modifiers);

        //获取成员变量的类型
        String name1 = name.getName();
        System.out.println(name1);

        //获取成员变量的类型
        Class<?> type = name.getType();
        System.out.println(type);

        System.out.println("----------------芝士分割线------------------");



        Student stu = new Student("佟gt",19,"男");


        //获取成员变量记录的值
        name.setAccessible(true);//临时取消权限校验,暴力反射获取
        Object o = name.get(stu);
        System.out.println(o);

        System.out.println("----------------芝士分割线------------------");

        //修改成员变量的值
        name.set(stu,"魔法少女tgt");
        gender1.setAccessible(true);
        gender1.set(stu,"沃尔沃塑料袋");
        String newName = stu.getName();
        String newGender = stu.getGender();
        System.out.println(newName);
        System.out.println(newGender);
    }
}

反射获取成员方法

public class MyReflectDemo3 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        Class clazz = Class.forName("MyReflectDemo1.Student");

        //获取所有公有的成员方法(包含父类中的方法)
        Method[] methods = clazz.getMethods();
        for(Method method : methods){
            System.out.println(method);
        }
        System.out.println("----------------芝士分割线------------------");

        //获取所有的方法(不能获取父类中的方法)
        Method[] methods1 = clazz.getDeclaredMethods();
        for (Method method : methods1){
            System.out.println(method);
        }
        System.out.println("----------------芝士分割线------------------");

        //获取指定名称的方法
        //若出现方法重名,则还需仔细指定参数列表
        Method eat1 = clazz.getDeclaredMethod("eat", String.class);
        System.out.println(eat1);
        Method eat2 = clazz.getDeclaredMethod("eat", String.class, String.class);
        System.out.println(eat2);
        System.out.println("----------------芝士分割线------------------");

        //获取指定名称的私有方法
        Method play = clazz.getDeclaredMethod("play");
        System.out.println(play);

        //获取指定名称的公有方法
        Method m = clazz.getMethod("study");
        System.out.println(m);
        System.out.println("----------------芝士分割线------------------");

        //获取方法名
        String methodName = m.getName();
        System.out.println(methodName);

        //获取方法的参数信息
        int parameterCount = eat2.getParameterCount();//方法的参数数量
        Class<?>[] parameterTypes = eat2.getParameterTypes();//方法参数的类型

        //直接获取参数
        Parameter[] parameters = eat2.getParameters();
        for (Parameter parameter : parameters){
            System.out.println(parameter);
        }

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

        //获取方法的修饰符
        int modifiers = eat2.getModifiers();
        System.out.println(modifiers);
        System.out.println("----------------芝士分割线------------------");

        //调用方法
        Student s = new Student();
        //s:方法的调用者,后面是方法参数
        //接收返回值
        Object o =eat1.invoke(s, "铁牛牛肉面");
        System.out.println(o);
    }
}

总结

反射可以获取一个类里面所有信息,获取到后,再执行其他业务逻辑。

结合配置文件,动态的创建对象并调用方法。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值