当前位置: 首页 > news >正文

关于java中的反射

理解反射:就是将类的各个组成部分封装为其他对象,这个就是反射机制。我们通过对生成类对象,获取类对象,使用类对象进行操作就是一个操作反射的过程。举个栗子:
先生成一个类对象

package org.example.doMain;/*
 *@author wanghongyuan
 *@Create 2021/1/24 17:15
 */

public class Person {
    //成员变量
    private String name;
    private int age;
    public String a;
    protected String b;
     String c;
    private String d;

    //构造方法
    public Person(){

    }

    public Person(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 "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", a='" + a + '\'' +
                ", b='" + b + '\'' +
                ", c='" + c + '\'' +
                ", d='" + d + '\'' +
                '}';
    }

    //成员方法
    public void eat(){

    }
}

三个阶段中对应生成类文件的三个方法

package org.example.Reflect;/*
 *@author wanghongyuan
 *@Create 2021/1/24 17:05
 */

import org.example.doMain.Person;

/*
    关于反射
    获取类的三种方式:
    类在程序中有三个阶段,这三个阶段获取类的方法各有不同,分别是下面三种:
    第一个阶段,这个阶段类还没有加载进内存,我们要获取这个类就需要手动将该类加载进内存
    使用的方法是class.forName("类全名");类全名就是:包名.类名
    这个阶段多用于配置文件中,将类名定义在配置文件中,读取文件,加载类。因为这个地方传的是一个字符串,在物理文件,配置文件读取的也是字符串。
    第二个阶段,这个时候类已经加载进内存了,我们直接类名.class就可以获取到该类对象
    使用的方法就是类.class,通过类名的属性class来获取
    这个阶段多用于参数的传递。
    第三个阶段,这个时候类已经加载进内存,并且生成了类对象,我们就可以通过类对象.getClass的方法来获取类对象
    使用的方法就是对象.getClass,getClass()方法在Object类中定义了。
    多用于对象的获取字节码方式
 */
public class reflectDemo01 {
    public static void main(String[] args) throws ClassNotFoundException {
        //1.class.forName("类全名")
        Class<?> cls1 = Class.forName("org.example.doMain.Person");
        System.out.println(cls1);
        //2.类.class
        Class cls2 = Person.class;
        System.out.println(cls2);
        //3.对象.getClass
        Person p = new Person();

        Class cls3 = p.getClass();
        System.out.println(cls3);
//==比较三个对象
        System.out.println(cls1==cls2);//true
        System.out.println(cls1==cls3);//true
        System.out.println(cls2==cls3);//true
        /*
            同一个字节码文件(*.class)在一次程序运行中,只会被加载一次
            ,不管是哪个阶段获取到的类对象,都是指向同一个字节码文件。
         */
    }
}

获取成员变量们

package org.example.Reflect;/*
 *@author wanghongyuan
 *@Create 2021/1/24 19:41
 */

import org.example.doMain.Person;

import java.lang.reflect.Field;

/*
    Class对象功能
        获取功能:
            1.获取成员变量们
                Field[] getFields():获取所有public修饰的成员变量
                Field getField(String name):获取指定名称的成员变量

                Field[] getDeclaredFields()获取所有的成员变量,不考虑修饰符。
                Field getDeclaredField(String name)获取指定名称的成员变量
                获取这些方法做什么操作,常见的就两个:
                    1.设置值
                        set(Object)
                    2.获取值
                        get(Object)

                    3.忽略访问权限修饰符的安全检查
                        d.setAccessible(true);//暴力反射

            2.获取构造方法们
                Constructor<?>[] getConstructors()
                Constructor<T> getConstructor(类<?>...parameterTypes)

                Constructor<T> getDeclaredConstructor(类<?>...parameterTypes)
                Constructor<?>[] getDeclaredConstructors()

            3.获取成员方法们
                Method[] getMethods()
                Method getMethod(String name,类<?>...parameterTypes)

                Method[] getDeclaredMethods()
                Method getDeclaredMethod(String name,类<?>...parameterTypes)

            4.获取类名
                String getName()
 */
public class ReflectDemo02 {
    public static void main(String[] args) throws Exception {
        //0. 获取一个Person的Class对象
        Class personClass = Person.class;
        System.out.println(personClass);
        Field[] fields = personClass.getFields();
        /*
         1.获取成员变量们
                Field[] getFields()
                Field getField(String name)

                Field[] getDeclaredFields()
                Field getDeclaredField(String name)
        */
        for (Field field : fields) {
            System.out.println(field);
        }
        //Field getField(String name)
        Field a = personClass.getField("a");
        System.out.println(a);
        //获取成员变量a的值
        Person p = new Person();
        Object value = a.get(p);
        System.out.println(value);
        //设置a的值
        a.set(p,"张三");
        System.out.println(p);

        System.out.println("===================");
        /*
            Field[] getDeclaredFields()
            Field getDeclaredField(String name)
         */
        //Field[] getDeclaredFields():获取所有的成员变量,不考虑修饰符。
        Field[] df = personClass.getDeclaredFields();
        for (Field field : df) {
            System.out.println("df:"+field);
        }
        //Field getDeclaredField(String name)
        Field d = personClass.getDeclaredField("d");
        System.out.println(d);
        //忽略访问权限修饰符的安全检查
        d.setAccessible(true);//暴力反射
        Object value2 = d.get(p);
        //d设置值,里面传对象名,和设置的值
        d.set(p,"赵四");
        System.out.println(p);

    }
}

·获取构造方法们

package org.example.Reflect;/*
 *@author wanghongyuan
 *@Create 2021/1/24 20:55
 */

import org.example.doMain.Person;
import org.mortbay.jetty.security.Constraint;

import java.lang.reflect.Constructor;

/*
      2.获取构造方法们
                Constructor<?>[] getConstructors()
                Constructor<T> getConstructor(类<?>...parameterTypes)

                Constructor<T> getDeclaredConstructor(类<?>...parameterTypes)
                Constructor<?>[] getDeclaredConstructors()

           Constructor:构造方法
            创建对象:
                T newInstance(Object...initargs)


           */
public class ReflectDemo03 {
    public static void main(String[] args) throws Exception {
        //获取Person的class对象
        Class<Person> personClass = Person.class;
        Constructor cs = personClass.getConstructor(String.class,int.class);
        //创建对象:
        Object person = cs.newInstance("张三", 23);
        System.out.println(person);
        System.out.println("----------------");
        //创建一个空参的对象
        Constructor cs1 = personClass.getConstructor();
        //创建对象:
        Object person1 = cs1.newInstance();
        System.out.println(person1);
        //如果使用空参数构造方法创建对象,操作可以简化:可以使用class对象里面的专门方法newInstance
        cs.setAccessible(true);//暴力破解,可以访问私有方法
        Person o = personClass.newInstance();
        System.out.println(o);

    }

}

获取成员方法们

package org.example.Reflect;/*
 *@author wanghongyuan
 *@Create 2021/1/24 21:57
 */

import org.example.doMain.Person;

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

/*
 3.获取成员方法们
                Method[] getMethods()
                Method getMethod(String name,类<?>...parameterTypes)

                Method[] getDeclaredMethods()
                Method getDeclaredMethod(String name,类<?>...parameterTypes)

    执行方法:
       Object invoke(Object obj(真实的对象),Object...args(方法的实际参数列表))
 */
public class ReflectDemo04 {
    public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        Class<Person> personClass = Person.class;
        //Method getMethod(String name,类<?>...parameterTypes)获取指定名称和指定参数列表的一个方法
        Method eat = personClass.getMethod("eat");
        Person p = new Person();
        //执行方法
        eat.invoke(p);//只传一个对象就可以了,因为这个方法没有参数
        //p.eat();

        //加个参数在方法中
        Method eat1 = personClass.getMethod("eat", String.class);
        eat1.invoke(p,"汉堡");
        System.out.println("----------------------------");
        //获取所有public修饰的方法,不止是自己创建的方法,还有Object的方法也在里面
        Method[] methods = personClass.getMethods();
        for (Method method : methods) {
            System.out.println(method);
            //获取方法的名称
            String name = method.getName();
            System.out.println(name);
            //method.setAccessible(true);//暴力反射,可以访问私有方法
        }
        //获取类名
        String className = personClass.getName();
        System.out.println(className);//org.example.doMain.Person


    }
}

```

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 通过反射写个“框架”
  • Postman中使用的参数
  • 注解(一)
  • 基于注解一个简单的测试框架
  • 数据库(一)
  • 数据库(二)
  • 数据库(三)
  • 数据库(四)
  • 数据库(五)
  • 数据库(六)
  • 数据库(七)
  • 0205
  • 数据库(八)
  • 数据库(九)
  • Httprunner使用指南
  • 2017-08-04 前端日报
  • java取消线程实例
  • JS数组方法汇总
  • js中forEach回调同异步问题
  • Linux CTF 逆向入门
  • Material Design
  • Mybatis初体验
  • October CMS - 快速入门 9 Images And Galleries
  • PV统计优化设计
  • 每个JavaScript开发人员应阅读的书【1】 - JavaScript: The Good Parts
  • 浅谈web中前端模板引擎的使用
  • 使用 QuickBI 搭建酷炫可视化分析
  • 想晋级高级工程师只知道表面是不够的!Git内部原理介绍
  • 新版博客前端前瞻
  • Mac 上flink的安装与启动
  • 资深实践篇 | 基于Kubernetes 1.61的Kubernetes Scheduler 调度详解 ...
  • ​马来语翻译中文去哪比较好?
  • (11)MATLAB PCA+SVM 人脸识别
  • (2020)Java后端开发----(面试题和笔试题)
  • (2024)docker-compose实战 (9)部署多项目环境(LAMP+react+vue+redis+mysql+nginx)
  • (39)STM32——FLASH闪存
  • (Redis使用系列) Springboot 实现Redis消息的订阅与分布 四
  • (阿里巴巴 dubbo,有数据库,可执行 )dubbo zookeeper spring demo
  • (层次遍历)104. 二叉树的最大深度
  • (算法)Travel Information Center
  • .\OBJ\test1.axf: Error: L6230W: Ignoring --entry command. Cannot find argumen 'Reset_Handler'
  • .java 9 找不到符号_java找不到符号
  • .net core 调用c dll_用C++生成一个简单的DLL文件VS2008
  • .Net6使用WebSocket与前端进行通信
  • .net反编译的九款神器
  • .net连接oracle数据库
  • .NET文档生成工具ADB使用图文教程
  • @autowired注解作用_Spring Boot进阶教程——注解大全(建议收藏!)
  • @selector(..)警告提示
  • @vue-office/excel 解决移动端预览excel文件触发软键盘
  • [ Linux ] git工具的基本使用(仓库的构建,提交)
  • [《百万宝贝》观后]To be or not to be?
  • [BZOJ 4598][Sdoi2016]模式字符串
  • [bzoj1038][ZJOI2008]瞭望塔
  • [C++]AVL树怎么转