前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >反射学习

反射学习

作者头像
晓果冻
发布2022-09-08 14:02:02
1770
发布2022-09-08 14:02:02
举报
文章被收录于专栏:一直在努力的Java菜鸡er

反射学习

应用场景
  • 通过反射机制访问java对象的属性、方法、构造方法等
  • JDBC加载驱动连接 Class.forname("com.mysql.jdbc.Driver");动态加载mysql驱动;
  • Spring容器框架IOC实例化对象
  • 自定义注解生效(反射+Aop
  • 第三方核心的框架 mybatis orm
优点
  • 在运行时获得类的各种内容,进行反编译,对于Java这种先编译再运行的语言,能够让我们很方便的创建灵活的代码,这些代码可以在运行时装配,无需在组件之间进行源代码的链接,更加容易实现面向对象。
缺点
  1. 反射会消耗一定的系统资源,因此如果不需要动态地创建一个对象,那么就不需要用反射。
  2. 反射调用方法时可以忽略权限检查,因此可能会破坏封装性而导致安全问题。
相关名词
代码语言:javascript
复制
Class类 代表类的实体,在运行的Java应用程序中表示类和接口
Field类 代表类的成员变量(成员变量也称为类的属性)
Method类 代表类的方法
Constructor类 代表类的构造方法
  • getField、getMethod和getCostructor方法可以获得指定名字的域、方法和构造器。
  • getFields、getMethods和getCostructors方法可以获得类提供的public域、方法和构造器数组,其中包括超类的共有成员。
  • getDeclatedFields、getDeclatedMethodsgetDeclaredConstructors方法可以获得类中声明的全部域、方法和构造器,其中包括私有和受保护的成员,但不包括超类的成员。
Demo
获取class的三种方式
代码语言:javascript
复制
//方式一
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("***************");
实例化
代码语言:javascript
复制
//调用无参构造函数
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);
属性查找赋值
代码语言:javascript
复制
//公有属性查找、赋值
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);
方法获取、调用
代码语言:javascript
复制
//获取所有方法
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);
利用反射越过泛型检查
代码语言:javascript
复制
//反射越过泛型检查 只在编译器检查
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
代码语言:javascript
复制
/**
 * @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
代码语言:javascript
复制
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

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-05-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 反射学习
    • 应用场景
      • 优点
        • 缺点
          • 相关名词
            • Demo
              • User.java
                • Main.java
                相关产品与服务
                容器服务
                腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
                领券
                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档