• java反射获取构造函数、成员变量、执行方法


    java反射机制:

    JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。

    要想解剖一个类,必须先要获取到该类的字节码文件对象。而解剖使用的就是Class类中的方法.所以先要获取到每一个字节码文件对应的Class类型的对象。

    测试类:

    package io.renren.modules.base;
    
    import lombok.Data;
    
    @Data
    public class ReflectionDemo {
    
        public String name;
    
        private String address;
        private int age;
    
        public ReflectionDemo(){
            System.out.println("空参构造方法");
        }
    
        private ReflectionDemo(String name){
            this.name = name;
        }
    
        public ReflectionDemo(String name,int age, String address){
            this.name = name;
            this.age = age;
            this.address = address;
        }
    
        public ReflectionDemo(String name,int age){
            this.age = age;
            this.name = name;
        }
    
      //公有方法
    public void eat(String food){ System.out.println("吃—"+food); }
      //私有方法
    private void save(Double money,Integer age){ System.out.println(""+this.name+"】存了【"+money+"】钱"+",今年:"+age+""); } }

    开始测试:

    package io.renren.modules.base;
    
    import org.junit.Test;
    import java.lang.reflect.Constructor;
    import java.lang.reflect.Field;
    import java.lang.reflect.Method;
    import java.net.URL;
    
    /**
     * java类要经过编译—>运行两个阶段,编译器把.java文件编译成.class文件,
     * 而运行时期,则需要把class文件读进内存,过程分为:加载到内存、连接解析、初始化
     * 加载:把class文件读进内存,然后再创建一个class对象
     * 连接:协调类的内部, 将类的二进制数据中的符号引用替换为直接引用
     * 初始化
     * 1. 创建类的实例
     * 2. 类的静态变量,或者为静态变量赋值
     * 3. 类的静态方法
     * 4. 使用反射方式来强制创建某个类或接口对应的java.lang.Class对象
     * 5. 初始化某个类的子类
     */
    
    //@SpringBootTest
    public class reflectionTest {
    
        /**
         * 获取类的加载器
         */
        @Test
        public void test1(){
            Class c = ReflectionDemo.class;
            System.out.println(c);
            Class<? extends Class> aClass = c.getClass();
            System.out.println(aClass);
            ClassLoader classLoader = c.getClassLoader();
            URL resource = classLoader.getResource("");
            System.out.println(resource);
    
        }
    
    
        /**
         * 获取类的class对象,字节码对象
         */
        @Test
        public void test2(){
            //第一种方法
            ReflectionDemo demo = new ReflectionDemo();
            Class<? extends ReflectionDemo> aClass = demo.getClass();
            System.out.println(aClass);
    
            //第二种方法
            Class c = ReflectionDemo.class;
            System.out.println(c);
    
            //第三种方法
            try {
                Class cn = Class.forName("io.renren.modules.base.ReflectionDemo");
                System.out.println(cn);
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
    
        }
    
        /**
         * 获取构造方法、成员变量、成员方法
         */
        @Test
        public void test3() throws Exception{
            //获取空参构造方法
            Class c = ReflectionDemo.class;
            //获取所有public构造方法
            Constructor[] constructors = c.getConstructors();
            for (Constructor con: constructors){
                System.out.println(con);
            }
    
            //获取所有的构造方法,包括私有、公共
            Constructor[] constructors1 = c.getDeclaredConstructors();
            for (Constructor con: constructors1){
                System.out.println(con);
            }
    
            //获取某个公共的构造方法,参数类型要对应
            Constructor constructor = c.getConstructor(String.class, Integer.class);
            ReflectionDemo object =(ReflectionDemo) constructor.newInstance("小明", 190);
            System.out.println(object);
    
    
            Constructor constructor1 = c.getConstructor();
            System.out.println(constructor1);
    
            //获取某个构造方法,包括私有、公有
            Constructor declaredConstructors = c.getDeclaredConstructor(String.class);
            Constructor declaredConstructors2 = c.getDeclaredConstructor(String.class, Integer.class);
            System.out.println(declaredConstructors+"====="+declaredConstructors2);
    
            //private,取消 Java 语言访问检查
            declaredConstructors.setAccessible(true);
            ReflectionDemo object2 =(ReflectionDemo) declaredConstructors.newInstance("小明");
            System.out.println(object2);
    
            //获取所有公有变量
            Field[] fields = c.getFields();
            for(Field f: fields){
                System.out.println(f);
            }
    
            //获取所有变量
            Field[] declaredFields = c.getDeclaredFields();
            for(Field f: declaredFields){
                System.out.println(f);
            }
    
            //获取公有变量
            Field ageField = c.getField("name");
            System.out.println(ageField);
    
            //获取所有公有方法
            Method[] method = c.getMethods();
            for(Method m: method){
                System.out.println(m);
            }
    
            //获取公有方法
            Method method1 = c.getMethod("eat", String.class);
            System.out.println(method1);
    
            //获取方法、包括私有、公有
            Method method2 = c.getDeclaredMethod("save", Double.class);
            method2.setAccessible(true);
            System.out.println(method2);
    
    
        }
    
    
        /**
         * 获取成员变量
         */
        @Test
        public void test4() throws Exception{
            Class c = ReflectionDemo.class;
            //获取到有参构造方法
            Constructor con = c.getDeclaredConstructor(String.class);
            //赋值
            con.setAccessible(true);
            Object object = con.newInstance("小明");
            System.out.println(object);
    
            Field name = c.getField("name");
            Object value1 = name.get(object);
    
            Field name2 = c.getDeclaredField("age");
            name2.setAccessible(true);
            Object value2 = name2.get(object);
    
            //没赋值,为null
            Field name3 = c.getDeclaredField("address");
            name3.setAccessible(true);
            Object value3 = name3.get(object);
    
            System.out.println(value1);
            System.out.println(value2);
            System.out.println(value3);
    
        }
    
        /**
         * 执行方法
         */
        @Test
        public void test5() throws Exception{
            Class c = Class.forName("io.renren.modules.base.ReflectionDemo");
    
            Constructor constructor = c.getDeclaredConstructor(String.class);
            constructor.setAccessible(true);
            Object object = constructor.newInstance("小明");
    
            Method eatMethod = c.getMethod("eat", String.class);
            eatMethod.invoke(object, "菜果");
    
            Method saveMethod = c.getDeclaredMethod("save", Double.class,Integer.class);
            saveMethod.setAccessible(true);
            //反射执行方法,object,实例对象,也就是执行哪个实例的方法,方法的参数
            saveMethod.invoke(object,200000d,24);
        }
    
    
    
    }
  • 相关阅读:
    在CentOS中配置DNS服务器
    CENTOS5.3 64位 VNC远程控制Centos 安装配置
    Windows Server 2003 FTP服务器配置详解 20091210 14:23:36| 分类: 服务器 | 标签: |字号大
    Centos 5.1 sendmail邮件服务器安装及配置
    DNS安装配置全过程
    tomcat多域名设置
    tomcat6 优化初步
    让CentOS自动备份mysql数据库 不指定
    开通企业邮箱之前,请登录您企业网站的域名注册服务商的域名管理平台,进行DNS配置及指向设置,谢谢您的配合
    18.3.2 在不同主机上使用 RMAN 备份建立物理备用数据库
  • 原文地址:https://www.cnblogs.com/caohanren/p/12487452.html
Copyright © 2020-2023  润新知