zoukankan      html  css  js  c++  java
  • 反射

    一、什么是反射

            java程序在运行期间能够动态加载、解析、使用一些在编译阶段并不确定的数据类型   

    二、反射的功能

           2.1、加载运行时才能确定的数据类型
           2.2、解析类的结构,获取内部信息
           2.3、操作该类型或其实例:访问属性、调用方法、创建新对象

    package com.study.test;
    
    import static java.lang.System.out;
    
    class aaa {
    
        void test() {
            out.println("您好!");
        }
    }
    
    public class ClassLoaderJZ {
    
        public static void main(String[] args) throws Exception {
            // 反射的概览
            // 传统的实现test方法的调用通过如下方式
            aaa a1 = new aaa();
            a1.test();
            // 通过反射来实现test方法的调用
            aaa.class.newInstance().test();// 获取类模板调用方法实例化对象,最后调用test方法,更加简洁
    
            // 返回默认的无参构造函数 返回类型为数组
            out.println(aaa.class.getDeclaredConstructors()[0]);
            out.println(aaa.class.getSuperclass());// 返回aaa的父类Object
    
            // 输出为空可知Object已经是最高的父类了,不能再回溯了
            out.println(aaa.class.getSuperclass().getSuperclass());
        }
    
    }

    三、获取Class对象的方法

           3.1、Class的静态函数forName()获取

           3.2、调用从Object继承下来的getClass()函数

           3.3、通过.class表达式获取

    package com.study.test;
    
    import static java.lang.System.out;
    
    class aaa {
    
        void test() {
            out.println("您好!");
        }
    }
    
    public class ClassLoaderJZ {
    
        public static void main(String[] args) throws Exception {
            // 获取Class对象的途径
            // 针对引用数据类型 
            //1、Class的静态函数forName()获取
            Class<?> c1 = Class.forName("com.study.test.aaa");
            out.println(c1);
            // 2、调用从Object继承下来的getClass()函数
            aaa a1 = new aaa();
            Class<?> c2 = a1.getClass();
            out.println(c2);
            // 3、通过.class表达式获取
            out.println(aaa.class);
            Class<aaa> c3 = aaa.class;
            out.println(c3);
    
            // 针对基本数据类型及void
            // 通过TYPE属性得到包装类的基本类型
            int i = 1;// 栈区存储 基本类型
            Integer j = new Integer(1);// 堆区存储 包装类 等于Integer j=1;
            Class<Integer> c4 = Integer.TYPE;// 输出int 返回包装类的基本类型
            out.println(c4);
    
            // 使用.class 表达式
            Class c5 = int.class;
            Class c6 = double.class;
            Class c7 = void.class;
            out.println(c5);
            out.println(c6);
            out.println(c7);
        }
    
    }

    四、反射操作构造函数

          4.1 调用无参、有一个参数、有多个参数的构造函数实例化对象

    package com.study.test;
    
    import static java.lang.System.out;
    
    import java.lang.reflect.Constructor;
    
    class aaa {
        aaa() {
            out.println("aaa()");
        }
    
        aaa(int i) {
            out.println("aaa(int i)");
        }
    
        aaa(int i, String j) {
            out.println("aaa(int i,String j)");
        }
    
        void test() {
            out.println("void test()");
        }
    
    }
    
    public class ClassLoaderJZ {
    
        public static void main(String[] args) throws Exception {
            // 通过反射我们获得了构造函数的规则 我们获得的是构造函数的数组
            out.println(aaa.class.getDeclaredConstructors().length);
            // out.println(aaa.class.getDeclaredConstructors()[0].newInstance());
            // out.println(aaa.class.getDeclaredConstructors()[1].newInstance(1));
            // 遍历输出构造函数 默认按参数个数的多少由大到小一次输出
            for (Constructor<?> c1 : (aaa.class.getDeclaredConstructors())) {
                out.println(c1);
    
            }
            // 怎样通过反射实例化调用函数?
            // aaa.class.newInstance().test(new int[]{4,5,6});
            // 错的aaa.class.getDeclaredConstructors()[0].newInstance(1);
    
            // //传统方案调用test
            // aaa a1=new aaa();
            // a1.test(new int[]{1,2,3});
    
            // 调用无参的构造函数动态生成实例
            // aaa.class.newInstance().test();
            aaa.class.getDeclaredConstructors()[2].newInstance();
            // 调用带一个参数构造函数生成实例
            aaa.class.getDeclaredConstructors()[1].newInstance(1);
    
            // 调用带两个参数构造函数生成实例
            aaa.class.getDeclaredConstructors()[0].newInstance(1, "abc");
    
        }
    
    }

    输出结果:

    3
    com.study.test.aaa(int,java.lang.String)
    com.study.test.aaa(int)
    com.study.test.aaa()
    aaa()
    aaa(int i)
    aaa(int i,String j)

    4.2  获取构造函数的修饰符、名字、以及参数

    package com.study.test;
    
    import static java.lang.System.out;
    
    import java.lang.reflect.Constructor;
    
    class aaa {
        aaa() {
            out.println("aaa()");
        }
    
        aaa(int i) {
            out.println("aaa(int i)");
        }
    
        aaa(int i, String j) {
            out.println("aaa(int i,String j)");
        }
    
        void test() {
            out.println("void test()");
        }
    
    }
    
    public class ClassLoaderJZ {
    
        public static void main(String[] args) throws Exception {
            // 通过反射我们获得了构造函数的规则 我们获得的是构造函数的数组
            out.println(aaa.class.getDeclaredConstructors().length);
            // out.println(aaa.class.getDeclaredConstructors()[0].newInstance());
            // out.println(aaa.class.getDeclaredConstructors()[1].newInstance(1));
            // 遍历输出构造函数 默认按参数个数的多少由大到小一次输出
            // getConstructors()函数获取public的构造函数;getDeclaredConstructors()获取所有的构造函数
            for (Constructor<?> c1 : (aaa.class.getDeclaredConstructors())) {
                // 获取构造函数的修饰符、名字、参数类型
                out.println("获取构造函数的修饰符、名字、参数类型");
                out.println(c1.getModifiers());
                out.println(c1.getName());
                for (Class c2 : c1.getParameterTypes()) {
                    out.println(c2);
                }
            }
    
        }
    
    }

    输出结果:

    3
    获取构造函数的修饰符、名字、参数类型
    0
    com.study.test.aaa
    int
    class java.lang.String
    获取构造函数的修饰符、名字、参数类型
    0
    com.study.test.aaa
    int
    获取构造函数的修饰符、名字、参数类型
    0
    com.study.test.aaa

    五、反射获取接口.

    package com.study.test;
    
    import static java.lang.System.out;
    
    interface I1 {
    
    }
    
    interface I2 {
    
    }
    
    class aaa implements I1, I2 {
        public aaa() {
            out.println("aaa()");
        }
    
        private aaa(int i) {
            out.println("aaa(int i)");
        }
    
        protected aaa(int i, String j) {
            out.println("aaa(int i,String j)");
        }
    
        void test() {
            out.println("void test()");
        }
    
    }
    
    public class ClassLoaderJZ {
    
        public static void main(String[] args) throws Exception {
    
            // 获取接口
            out.println("获取接口");
            for (Class<?> c2 : aaa.class.getInterfaces()) {
                out.println(c2);
            }
    
        }
    
    }

    输出结果:

    获取接口
    interface com.study.test.I1
    interface com.study.test.I2

    六、反射获取方法的返回类型,修饰符,参数类型等等

    package com.study.test;
    
    import static java.lang.System.out;
    
    import java.lang.reflect.Method;
    
    interface I1 {
    
    }
    
    interface I2 {
    
    }
    
    class aaa implements I1, I2 {
        public aaa() {
            out.println("aaa()");
        }
    
        private aaa(int i) {
            out.println("aaa(int i)");
        }
    
        protected aaa(int i, String j) {
            out.println("aaa(int i,String j)");
        }
    
        void test() throws Exception {
            out.println("void test()");
        }
    
        void test1() {
            out.println("void test1()");
        }
    
        void test2() {
            out.println("void test2()");
        }
    
    }
    
    public class ClassLoaderJZ {
    
        public static void main(String[] args) throws Exception {
    
            // getMethod()方法获得所有public的方法包括从Object继承的方法
            // for(Method m:aaa.class.getMethods()){
            // out.println(m);
            // };
            // getDeclaredMethods()方法获得所有在本类中自己声明的方法
            for (Method m : aaa.class.getDeclaredMethods()) {
                out.println("输出方法的返回类型,参数类型,修饰符,以及方法的异常类型");
    
                out.println(m.getReturnType());
                out.println(m.getParameters().length);
                out.println(m.getModifiers());
                for (Class c : m.getExceptionTypes()) {
                    out.println(m);
                }
    
            }
    
        }
    
    }

    输出结果:

    输出方法的返回类型,参数类型,修饰符,以及方法的异常类型
    void
    0
    0
    void com.study.test.aaa.test() throws java.lang.Exception
    输出方法的返回类型,参数类型,修饰符,以及方法的异常类型
    void
    0
    0
    输出方法的返回类型,参数类型,修饰符,以及方法的异常类型
    void
    0
    0

    七、通过反射调用方法

    package com.study.test;
    
    import static java.lang.System.*;
    
    import java.lang.reflect.Constructor;
    import java.lang.reflect.Method;
    
    interface I1 {
    
    }
    
    interface I2 {
    
    }
    
    class aaa implements I1, I2 {
    
        public aaa() {
            out.println("aaa()");
        }
    
        public aaa(int i) {
            out.println("aaa(int i)");
        }
    
        protected aaa(int i, int j) {
            out.println("aaa(int i,String j)");
        }
    
        public void test() {
            out.println("void test()");
        }
    
        public void test1(int i) {
            out.println("void test1()");
        }
    
        void test2(int j, int k) {
            out.println("void test2()");
        }
    
    }
    
    public class ClassLoaderJZ {
    
        public static void main(String[] args) throws Exception {
    
            // getMethod()方法获得所有public的方法包括从Object继承的方法
            // for(Method m:aaa.class.getMethods()){
            // out.println(m);
            // };
            // getDeclaredMethods()方法获得所有在本类中自己声明的方法
            out.println("获得所有在本类中自己声明的方法");
            for (Method m : aaa.class.getDeclaredMethods()) {
                out.println(m);
            }
            // 注意:遍历出的构造函数是无序的
            out.println("构造函数");
            for (Constructor c : aaa.class.getDeclaredConstructors()) {
                out.println(c);
            }
            out.println("方法调用");
            aaa.class.getDeclaredMethods()[0].invoke(aaa.class.getDeclaredConstructors()[2].newInstance(), null);
            aaa.class.getDeclaredMethods()[1].invoke(aaa.class.getDeclaredConstructors()[1].newInstance(1), 1);
        }
    
    }

    输出结果:

    获得所有在本类中自己声明的方法
    public void com.study.test.aaa.test()
    public void com.study.test.aaa.test1(int)
    void com.study.test.aaa.test2(int,int)
    构造函数
    protected com.study.test.aaa(int,int)
    public com.study.test.aaa(int)
    public com.study.test.aaa()
    方法调用
    aaa()
    void test()
    aaa(int i)
    void test1()

    八、反射得到所有的字段

    package com.study.test;
    
    import static java.lang.System.out;
    
    import java.io.IOException;
    import java.lang.reflect.Field;
    
    class aa {
        private int j = 2;
        public static int i = 1;
    
        void test1(int i) throws Exception, IOException {
            out.println("test");
        }
    
        public static int test2() {
            out.println("test1");
            return 1;
        }
    
    }
    
    public class ClassLoaderJZ {
        public static void main(String[] args) throws NoSuchFieldException, SecurityException, IllegalArgumentException,
                IllegalAccessException, InstantiationException {
            // 得到第一个字段内容
            Field f1 = aa.class.getDeclaredField("j");
            f1.setAccessible(true);
            out.println(f1.get(aa.class.newInstance()));
            // 得到第二个字段内容
            out.println(aa.class.getDeclaredField("i").get(null));
    
        }
    }

    输出结果:

    2
    1

  • 相关阅读:
    Python中把数据存入csv文件
    Python中把字典和值取出来
    scrapy输出请求状态码
    scrapy发送post请求获取cookie
    Python3 Unicode转中文
    Quartus13.0破解方法
    元音字母A的发音规则
    位bit——字节Byte???
    曾经的小孩在努力奔跑!
    如何看懂的时序图?
  • 原文地址:https://www.cnblogs.com/leeSmall/p/7633139.html
Copyright © 2011-2022 走看看