侧边栏壁纸
博主头像
晓果冻博主等级

一个热爱生活的95后精神小伙

  • 累计撰写 131 篇文章
  • 累计创建 15 个标签
  • 累计收到 67 条评论

目 录CONTENT

文章目录

反射学习

晓果冻
2022-05-24 / 0 评论 / 0 点赞 / 432 阅读 / 1,343 字
温馨提示:
本文最后更新于 2022-05-24,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

反射学习

应用场景
  • 通过反射机制访问java对象的属性、方法、构造方法等
  • JDBC加载驱动连接 Class.forname("com.mysql.jdbc.Driver");动态加载mysql驱动;
  • Spring容器框架IOC实例化对象
  • 自定义注解生效(反射+Aop
  • 第三方核心的框架 mybatis orm
优点
  • 在运行时获得类的各种内容,进行反编译,对于Java这种先编译再运行的语言,能够让我们很方便的创建灵活的代码,这些代码可以在运行时装配,无需在组件之间进行源代码的链接,更加容易实现面向对象。
缺点
  1. 反射会消耗一定的系统资源,因此如果不需要动态地创建一个对象,那么就不需要用反射。
  2. 反射调用方法时可以忽略权限检查,因此可能会破坏封装性而导致安全问题。
相关名词
Class类 代表类的实体,在运行的Java应用程序中表示类和接口
Field类 代表类的成员变量(成员变量也称为类的属性)
Method类 代表类的方法
Constructor类 代表类的构造方法
  • getField、getMethod和getCostructor方法可以获得指定名字的域、方法和构造器。

  • getFields、getMethods和getCostructors方法可以获得类提供的public域、方法和构造器数组,其中包括超类的共有成员。

  • getDeclatedFields、getDeclatedMethodsgetDeclaredConstructors方法可以获得类中声明的全部域、方法和构造器,其中包括私有和受保护的成员,但不包括超类的成员。

Demo
获取class的三种方式
//方式一
Class userClass = Class.forName("com.example.test.反射.User");
System.out.println(userClass);
System.out.println("*************");
//方式二
Class userClass2 = User.class;
System.out.println(userClass);
System.out.println("*************");
//方式三
User user = new User();
Class userClass3 = user.getClass();
System.out.println(userClass3);
System.out.println("***************");
实例化
//调用无参构造函数
User user1 = (User) userClass2.newInstance();
//调用有参构造函数
Constructor<?> declaredConstructor =userClass2.getDeclaredConstructor(String.class,Integer.class,String.class);
User user2 = (User)declaredConstructor.newInstance("张三",28,"张三丰");
System.out.println(user2.toString());
System.out.println(user1==user2);
属性查找赋值
//公有属性查找、赋值
User user4 = (User)userClass.newInstance();
Field publicName = userClass.getDeclaredField("publicName");
publicName.set(user4,"晓果冻");
System.out.println(user4.toString());

//私有属性查找、赋值
User user5 = (User)userClass.newInstance();
Field name = userClass.getDeclaredField("name");
//反射访问私有属性
name.setAccessible(true);
name.set(user5,"晓果冻5");
System.out.println(user5.toString());
System.out.println(user4==user5);
方法获取、调用
//获取所有方法
User user6 = (User)userClass.newInstance();
//获取所有方法
Method[] methods = userClass.getMethods();
for(Method method:methods){
System.out.println(method);
}

//只能获取公共的方法
Method getName = userClass.getMethod("getName");

Method sumMethod = userClass.getDeclaredMethod("sum",Integer.class,Integer.class);
sumMethod.setAccessible(true);
Object total = sumMethod.invoke(user6,1,2);
System.out.println(total);
利用反射越过泛型检查
//反射越过泛型检查 只在编译器检查
ArrayList<String> arrayList = new ArrayList<>();
arrayList.add("晓果冻");
Class<? extends ArrayList> aClass =  arrayList.getClass();
Method addMethod = aClass.getDeclaredMethod("add", Object.class);
addMethod.invoke(arrayList,1);
System.out.println(arrayList);

全部代码

User.java
/**
 * @author 晓果冻
 * @version 1.0
 * @date 2022/5/24 14:19
 */
public class User {
    private String name;

    private Integer age;

    public String publicName;

    public User(String name, Integer age, String publicName) {
        System.out.println("有参构造函数");
        this.name = name;
        this.age = age;
        this.publicName = publicName;
    }

    public User() {
    }

    public String getName() {
        return name;
    }

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

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public String getPublicName() {
        return publicName;
    }

    public void setPublicName(String publicName) {
        this.publicName = publicName;
    }

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

    private Integer sum(Integer a,Integer b){
        return a+b;
    }
}
Main.java
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;

/**
 * @author 晓果冻
 * @version 1.0
 * @date 2022/5/24 14:20
 */
public class Main {
    public static void main(String[] args) throws Exception {
        //方式一
        Class userClass = Class.forName("com.example.test.反射.User");
        System.out.println(userClass);
        System.out.println("*************");
        //方式二
        Class userClass2 = User.class;
        System.out.println(userClass);
        System.out.println("*************");
        //方式三
        User user = new User();
        Class userClass3 = user.getClass();
        System.out.println(userClass3);
        System.out.println("***************");

        //调用无参构造函数
        User user1 = (User) userClass2.newInstance();
        //调用有参构造函数
        Constructor<?> declaredConstructor =userClass2.getDeclaredConstructor(String.class,Integer.class,String.class);
        User user2 = (User)declaredConstructor.newInstance("张三",28,"张三丰");
        System.out.println(user2.toString());
        System.out.println(user1==user2);

        //公有属性查找、赋值
        User user4 = (User)userClass.newInstance();
        Field publicName = userClass.getDeclaredField("publicName");
        publicName.set(user4,"晓果冻");
        System.out.println(user4.toString());

        //私有属性查找、赋值
        User user5 = (User)userClass.newInstance();
        Field name = userClass.getDeclaredField("name");
        //反射访问私有属性
        name.setAccessible(true);
        name.set(user5,"晓果冻5");
        System.out.println(user5.toString());
        System.out.println(user4==user5);

        //获取所有方法
        User user6 = (User)userClass.newInstance();
        //获取所有方法
        Method[] methods = userClass.getMethods();
        for(Method method:methods){
            System.out.println(method);
        }

        //只能获取公共的方法
        Method getName = userClass.getMethod("getName");

        Method sumMethod = userClass.getDeclaredMethod("sum",Integer.class,Integer.class);
        sumMethod.setAccessible(true);
        Object total = sumMethod.invoke(user6,1,2);
        System.out.println(total);


        //反射越过泛型检查 只在编译器检查
        ArrayList<String> arrayList = new ArrayList<>();
        arrayList.add("晓果冻");
        Class<? extends ArrayList> aClass =  arrayList.getClass();
        Method addMethod = aClass.getDeclaredMethod("add", Object.class);
        addMethod.invoke(arrayList,1);
        System.out.println(arrayList);


    }
}

代码仓库地址:https://gitee.com/cgd0526/demo/tree/master/src/main/java/com/example/test/%E5%8F%8D%E5%B0%84

0

评论区