Java-反射

  Java反射是Java编程语言中的一个重要特性,它允许程序在运行时获取类的信息,操作对象的内部结构,甚至动态地创建和操作对象。反射机制使得Java程序具有了更高的灵活性和扩展性,可以在不修改代码的情况下实现一些动态的功能。

一、 获取Class对象

要使用反射机制,首先需要获取一个Class对象,它表示我们要操作的类。获取Class对象的方式如下:

(1)、类名.class。
(2)、包名+类名:Class.forName("全类名")。
(3)、对象名.getclass。

例:

package com.wedu.Reflect1;

public class Person {
    public   Integer id;
    private String color;
    private  Integer age;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }
}
public class ReflectDemo1 {
    //获取class对象的方式
    public static void main(String[] args) throws ClassNotFoundException {
       //类名.class
        Class<Person> class1= Person.class;
        System.out.println(class1);
       //包名+类名
        Class<?> class2 = Class.forName("com.wedu.Reflect1.Person");
        System.out.println(class2);
       //对象.getClass
        Person person = new Person();
        Class<? extends Person> class3 = person.getClass();
        System.out.println(class3);

        System.out.println(class1==class2);
        System.out.println(class2==class3);
    }
}

二、反射获取构造方法

1、方法介绍

Constructor<?>[] getConstructors()返回所有公共构造方法对象的数组
Constructor<?>[] getDeclaredConstructors()返回所有构造方法对象的数组
Constructor<T> getConstructor(Class<?>... parameterTypes)返回单个公共构造方法对象
Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes)返回单个构造方法对象
package com.wedu.Reflect1;

public class Student {
    private String name;
    private int age;
    //共有的无参
    public Student() {
    }

    //共有的有参构造方法
    public Student(String name, int age) {
        this.name = name;
        this.age = age;
        System.out.println("name的值为:"+name+"age的值为:"+age);
        System.out.println("共有的有参构造方法");
    }

    //私有的有参构造方法
    private Student(String name){
        System.out.println("name的值为:"+name);
        System.out.println("私有的有参构造方法");
    }

    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 study(){
        System.out.println("学生在学习");
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
package com.wedu.Reflect1;

import java.lang.reflect.Constructor;

public class ReflectDemo2 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException {
        //获取字节码对象
        Class clazz = Class.forName("com.wedu.Reflect1.Student");
       //返回所有的公共的构造方法的数组对象
        Constructor[] constructors1= clazz.getConstructors();
        for (Constructor constructor : constructors1) {
            System.out.println(constructor);
        }
      
        //返回所有的构造方法的数组对象
        Constructor[] constructors2 = clazz.getDeclaredConstructors();
        for (Constructor constructor : constructors2) {
            System.out.println(constructors2);
        }
       
        //返回单个公共构造方法对象
        Constructor constructor1 = clazz.getConstructor();
        System.out.println(constructor1);
       
        Constructor constructor2 = clazz.getConstructor(String.class, int.class);
        System.out.println(constructor2);
       
        //返回单个构造方法的对象
        Constructor constructor = clazz.getDeclaredConstructor(String.class);
        System.out.println(constructor);

    }
}

2、Constructor类用于创建对象的方法

方法名说明
T newInstance(Object...initargs)根据指定的构造方法创建对象
setAccessible(boolean flag)设置为true,表示取消访问检查
package com.wedu.Reflect1;

public class Student3 {
    private String name;
    private int age;

    public Student3() {
    }

    public Student3(String name) {
        this.name = name;
    }

    protected Student3(int age) {
        this.age = age;
    }

    private Student3(String name, int age) {
        this.name = name;
        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;
    }

    @Override
    public String toString() {
        return "Student3{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
package com.wedu.Reflect1;

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

public class ReflectDemo3 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        //获取class字节码文件对象
        Class clazz = Class.forName("com.wedu.Reflect1.Student3");
        //获取公共的构造方法
        Constructor[] cons1 = clazz.getConstructors();
        for (Constructor con : cons1) {
            System.out.println(con);
        }
        System.out.println("---------------------------------------------------------------------");

        //获取所有的构造方法
        Constructor[] cons2 = clazz.getDeclaredConstructors();
        for (Constructor con : cons2) {
            System.out.println(con);
        }
        System.out.println("------------------------------------------------------------------------");
        //获取单个构造方法
        Constructor con1 = clazz.getDeclaredConstructor();
        System.out.println(con1);

        Constructor con2 = clazz.getDeclaredConstructor(String.class);
        System.out.println(con2);

        Constructor con3 = clazz.getDeclaredConstructor(int.class);
        System.out.println(con3);

        Constructor con4 = clazz.getDeclaredConstructor(String.class,int.class);
        System.out.println(con4);
        System.out.println("--------------------------------------------------------------------------");

        con4.setAccessible(true);//表示临时取消权限校验
        Student3 stu = (Student3) con4.newInstance("张三", 23);
        System.out.println(stu);


    }
}

三、反射获取成员属性

Field[] getFields()返回所有公共成员变量对象的数组
Field[] getDeclaredFields()返回所有成员变量对象的数组
Field getField(String name)返回单个公共成员变量对象
Field getDeclaredField(String name)返回单个成员变量对象
package com.wedu.Reflect1;

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

    public Student4() {
    }

    public Student4(String name, int age, String gender) {
        this.name = name;
        this.age = age;
        this.gender = gender;
    }

    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 String getGender() {
        return gender;
    }

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

    @Override
    public String toString() {
        return "Student4{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", gender='" + gender + '\'' +
                '}';
    }
}
package com.wedu.Reflect1;

import java.lang.reflect.Field;

public class ReflectDemo4 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException {
        //获取字节码
        Class clazz = Class.forName("com.wedu.Reflect1.Student4");
        //获取所有的成员变量
        Field[] declaredFields = clazz.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            System.out.println(declaredField);

        }
        //获取单个的成员变量
        Field name = clazz.getDeclaredField("name");
        System.out.println(name);

        //获取权限修饰符
        int modifiers = name.getModifiers();
        System.out.println(modifiers);

        //获取成员变量的名字
        String n = name.getName();
        System.out.println(n);

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

        //获取成员变量记录的值
        Student4 s=new Student4("zhangsan",23,"男");
        name.setAccessible(true);//暴力反射
        Object value = name.get(s);
        System.out.println(value);


    }

}

四、反射获取成员方法

Method[] getMethods()返回所有公共成员方法对象的数组,包括继承的
Method[] getDeclaredMethods()返回所有成员方法对象的数组,不包括继承的
Method getMethod(String name, Class<?>... parameterTypes)返回单个公共成员方法对象
Method getDeclaredMethod(String name, Class<?>... parameterTypes)返回单个成员方法对象

         

package com.wedu.Reflect1;

import java.io.IOException;

public class Student5 {
    private  String name;
    private  int age;

    public Student5() {
    }

    public Student5(String name, int age) {
        this.name = name;
        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 sleep(){
        System.out.println("睡觉");
    }

    private String eat(String something)throws IOException,NullPointerException {
        System.out.println("在吃"+something);
        return "好好吃";
    }

    private void eat(String something,int a){
        System.out.println("在吃"+something);
    }


    @Override
    public String toString() {
        return "Student5{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

     

package com.wedu.Reflect1;

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

public class ReflectDemo5 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        //获取字节码文件
        Class clazz = Class.forName("com.wedu.Reflect1.Student5");
        //获取所有的成员方法(包括父类中的所有公共方法)
        Method[] methods = clazz.getMethods();
        for (Method method : methods) {
            System.out.println(method);
        }
        System.out.println("-------------------------------------------------------");

        //获取所有的方法对象(不能获取父类的,但是可以本类中私有的)
        Method[] declaredMethods = clazz.getDeclaredMethods();
        for (Method declaredMethod : declaredMethods) {
            System.out.println(declaredMethod);

        }
        System.out.println("-------------------------------------------------------");


        //获取指定的单一方法
        Method m = clazz.getDeclaredMethod("eat", String.class);
        System.out.println(m);
        System.out.println("-------------------------------------------------------");

        //获取方法的修饰符
        int modifiers = m.getModifiers();
        System.out.println(modifiers);
        System.out.println("-------------------------------------------------------");

        //获取方法的名字
        String name = m.getName();
        System.out.println(name);
        System.out.println("-------------------------------------------------------");

        //获取方法的形参
        Class[] parameterTypes = m.getParameterTypes();
        for (Class parameterType : parameterTypes) {
            System.out.println(parameterType);
        }
        System.out.println("-------------------------------------------------------");

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

        //运行方法
        Student5 s=new Student5();
        m.setAccessible(true);
        //s表示方法的调用者,“蛋糕”表示在调用方法的时候传递的实际参数
        String result = (String) m.invoke(s, "蛋糕");
        System.out.println(result);
    }
}

五、应用场景

Java反射机制有很多应用场景,例如:

1、动态代理:通过反射机制,我们可以动态地生成代理类,实现对方法的拦截和增强。
2、 插件化开发:通过反射机制,我们可以动态地加载和卸载插件,实现程序的扩展和定制。
3、ORM框架:通过反射机制,我们可以将Java对象和数据库表进行映射,实现对象的持久化和查询。

六、 总结

  Java反射机制是Java编程语言中的一个重要特性,它允许程序在运行时获取类的信息,操作对象的内部结构,甚至动态地创建和操作对象。反射机制使得Java程序具有了更高的灵活性和扩展性,可以在不修改代码的情况下实现一些动态的功能。本文通过实例介绍了Java反射的使用方法和应用场景,希望对你有所帮助。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值