• 重学java基础----反射


    参考于韩顺平老师JAVA基础课程以及笔记

    反射

    在这里插入图片描述

    引入反射

    在这里插入图片描述

    • 创建配置文件
    classfullpath=com.fanshe.Cat
    method=hi
    package com.fanshe;
    
    /**
     * @Description
     * @autor wzl
     * @date 2022/8/19-9:04
     */
    public class Cat {
        private String name="招财猫";
        public void hi(){
            System.out.println("hi"+name);
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 编写测试方法
    package com.fanshe;
    
    import com.file.network.SocketTcp01Client;
    
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.IOException;
    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;
    import java.util.Properties;
    
    /**
     * @Description
     * @autor wzl
     * @date 2022/8/19-9:05
     */
    public class Reflection01 {
        public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, IOException, NoSuchMethodException, InvocationTargetException {
            Properties properties = new Properties();
            properties.load(new FileInputStream("src\\re.properties"));
            String classfullpath = properties.getProperty("classfullpath");
            String methodName = properties.getProperty("method");
            System.out.println("classfullpath="+classfullpath);
            System.out.println("method="+methodName);
    
    
            //1.加载类,返回class类型的对象cls
            Class cls = Class.forName(classfullpath);
            //2.通过cls得到加载的类  com.wzl.Cat的对象实例
            Object o = cls.newInstance();
            System.out.println("o的运行类型为:" + o.getClass());
            //3.通过cls得到加载类的 methodName "hi"的方法对象
            Method method = cls.getMethod(methodName);
            //4.通过method调用方法:通过方法对象实现调用方法
            System.out.println("-------");
            method.invoke(o);//传统方法:对象.方法()  ,反射机制  方法.invoke(对象)
    
    
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40

    反射机制原理图(重要

    在这里插入图片描述
    在这里插入图片描述

    反射相关的类

    在这里插入图片描述

    package com.fanshe;
    
    /**
     * @Description
     * @autor wzl
     * @date 2022/8/19-9:04
     */
    public class Cat {
        private String name="招财猫";
        public int age=10;
        public Cat(){}
        public Cat(String name){
            this.name=name;
        }
        public void hi(){
            System.out.println("hi"+name);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    package com.fanshe;
    
    import java.io.FileInputStream;
    import java.lang.reflect.Constructor;
    import java.lang.reflect.Field;
    import java.lang.reflect.Method;
    import java.util.Properties;
    
    /**
     * @Description
     * @autor wzl
     * @date 2022/8/19-9:37
     */
    public class Refletion02 {
        public static void main(String[] args) throws Exception{
            Properties properties = new Properties();
            properties.load(new FileInputStream("src\\re.properties"));
            String classfullpath = properties.getProperty("classfullpath");
            String methodName = properties.getProperty("method");
            System.out.println("classfullpath="+classfullpath);
            System.out.println("method="+methodName);
    
    
            //1.加载类,返回class类型的对象cls
            Class cls = Class.forName(classfullpath);
            //2.通过cls得到加载的类  com.wzl.Cat的对象实例
            Object o = cls.newInstance();
            System.out.println("o的运行类型为:" + o.getClass());
            //3.通过cls得到加载类的 methodName "hi"的方法对象
            Method method = cls.getMethod(methodName);
            //4.通过method调用方法:通过方法对象实现调用方法
            System.out.println("-------");
            method.invoke(o);//传统方法:对象.方法()  ,反射机制  方法.invoke(对象)
    
            //java.lang.reflect.Field: 代表类的成员变量, Field 对象表示某个类的成员变量
            //得到 name 字段
            //getField 不能得到私有的属性
            //Field name = cls.getField("name");//运行出错
            Field age = cls.getField("age");
            System.out.println(age.get(o)); // 传统 对象.成员变量  反射:成员变量.get(对象)
    
            //java.lang.reflect.Constructor: 代表类的构造方法, Constructor 对象表示构造器
            Constructor constructor = cls.getConstructor();//无参构造器
            System.out.println(constructor);
    
            Constructor constructor1 = cls.getConstructor(String.class);// String.class 就是 String 类Class 对象
            System.out.println(constructor1);
    
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50

    反射机制优点、缺点

    在这里插入图片描述

    package com.fanshe;
    
    /**
     * @Description
     * @autor wzl
     * @date 2022/8/19-9:04
     */
    public class Cat {
        private String name="招财猫";
        public int age=10;
        public Cat(){}
        public Cat(String name){
            this.name=name;
        }
        public void hi(){
    
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    package com.fanshe;
    
    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;
    
    /**
     * @Description
     * @autor wzl
     * @date 2022/8/19-9:45
     * 测试反射调用性能,和优化方案
     */
    public class Reflection03 {
        public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
    
            m1();
            m2();
            m3();
        }
    
        //传统方法调用hi()
        public static void m1(){
            Cat cat = new Cat();
            long start = System.currentTimeMillis();
            for (int i = 0; i < 900000000; i++) {
                cat.hi();
            }
            long end = System.currentTimeMillis();
            System.out.println("m1()耗时="+(end-start));
        }
        //反射机制调用
        public static void m2() throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
            Class cls = Class.forName("com.fanshe.Cat");
            Object o = cls.newInstance();
            Method hi = cls.getMethod("hi");
            long start = System.currentTimeMillis();
            for (int i = 0; i < 900000000; i++) {
                hi.invoke(o);
            }
            long end = System.currentTimeMillis();
            System.out.println("m2()耗时"+(end-start));
    
        }
        //反射机制调用优化+关闭访问检查
        public static void m3() throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
            Class cls = Class.forName("com.fanshe.Cat");
            Object o = cls.newInstance();
            Method hi = cls.getMethod("hi");
            hi.setAccessible(true);//在反射调用方法时,取消访问检查
            long start = System.currentTimeMillis();
            for (int i = 0; i < 900000000; i++) {
                hi.invoke(o);
            }
            long end = System.currentTimeMillis();
            System.out.println("m2()耗时"+(end-start));
    
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 简单优化
      在这里插入图片描述

    在这里插入图片描述

    Class类

    • 介绍
      在这里插入图片描述
      在这里插入图片描述
    package com.class_;
    
    import com.fanshe.Cat;
    
    /**
     * @Description
     * @autor wzl
     * @date 2022/8/19-9:58
     */
    public class class_01 {
        public static void main(String[] args) throws ClassNotFoundException {
            //1.Class类对象不是new出来的,而是系统创建的
            //2.传统new对象
    
            /*ClassLoader类
             public Class loadClass(String name) throws ClassNotFoundException {
            return loadClass(name, false);
           }
             */
            Cat cat = new Cat();
    
            //2.反射方法
            /*ClassLoader类,依然通过ClassLoader类加载Cat类的 Class对象
             public Class loadClass(String name) throws ClassNotFoundException {
            return loadClass(name, false);
           }
             */
            Class aClass = Class.forName("com.fanshe.Cat");
            Class aClass1 = Class.forName("com.fanshe.Cat");
    
            //3. 对于某个类的Class类对象,在内存中只有一份,因为类只加载一次
            System.out.println(aClass.hashCode()); //21685669
            System.out.println(aClass1.hashCode());//21685669
    
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    在这里插入图片描述

    • 常用方法
      在这里插入图片描述
    package com.class_;
    
    import java.lang.reflect.Field;
    
    /**
     * @Description
     * @autor wzl
     * @date 2022/8/19-10:20
     */
    public class class_02 {
        public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchFieldException {
            //标识不确定的java类型
            //获取到Car类对应的Class对象
            Class<?> cls = Class.forName("com.class_.Car");
            //2.输出cls
            System.out.println(cls);//显示cls对象,是哪个类的Class对象 com.class_.Car
            System.out.println(cls.getClass());//cls运行类型 java.lang.Class
            //3.得到包名
            System.out.println(cls.getPackage().getName());//包名 com.class_
            //4.得到全类名
            System.out.println(cls.getName());//全类名 com.class_.Car
            //5.通过cls创建对象实例
            Object o = cls.newInstance();
            Car car=(Car)o;
    
            System.out.println(car);//car.tostring()Car{brand='宝马', price=0, color='null'}
    
            //6.通过反射获取属性 brand
            Field brand = cls.getField("brand");
            System.out.println(brand.get(car));//成员变量.对象  宝马
            //7.通过反射给属性赋值
            brand.set(car,"奔驰");//brand.set(对象,值)
            System.out.println(brand.get(car));//奔驰
    
            //8.得到所有属性/字段
            Field[] fields = cls.getFields();
            for (Field f : fields) {
                System.out.println(f.getName());//名称brand
                //price
                        //color
            }
    
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44

    获取Class对象的方式

    • 方式1----Class.forName(),用于读取配置文件
    • 方式2----类名.class,用于参数传递
    • 方式3----对象.getClass(),有对象实例
    • 方式4----类加载器
    • 方式5----基本数据类型.class
    • 方式6----基本数据类型对应的包装类.TYPE
      在这里插入图片描述
    package com.class_;
    
    /**
     * @Description
     * @autor wzl
     * @date 2022/8/19-10:36
     */
    public class getClass_ {
        public static void main(String[] args) throws ClassNotFoundException {
            //方式1 Class.forName
            Class<?> cls1 = Class.forName("com.class_.Car");
            System.out.println(cls1);//class com.class_.Car
    
            //2.类名.class, 多用于参数传递
            Class<Car> cls2 = Car.class;
            System.out.println(cls2);//class com.class_.Car
    
            //3.对象.getClass(),应用场景,有对象实例
            Car car = new Car();
            Class<? extends Car> cls3 = car.getClass();
            System.out.println(cls3);//class com.class_.Car
    
            //4.通过类加载器[4种]来获取到类的Class对象
            //1.先得到类加载器car
            ClassLoader classLoader = car.getClass().getClassLoader();
            //2.通过类加载得到Class对象
            Class<?> cls4 = classLoader.loadClass("com.class_.Car");
            System.out.println(cls4);//class com.class_.Car
    
            System.out.println(cls1.hashCode());//21685669
            System.out.println(cls2.hashCode());//21685669
            System.out.println(cls3.hashCode());//21685669
            System.out.println(cls4.hashCode());//21685669
    
            //5.基本数据(int, char,boolean,float,double,byte,long,short) 按如下方式得到 Class 类对象
            Class<Integer> integerClass = int.class;
            Class<Character> characterClass = char.class;
            Class<Boolean> booleanClass = boolean.class;
            System.out.println(integerClass);
    
            //6. 基本数据类型对应的包装类,可以通过 .TYPE 得到 Class 类对象
            Class<Integer> type = Integer.TYPE;
            System.out.println(type.hashCode());//2133927002
            System.out.println(integerClass.hashCode());//2133927002
    
    
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48

    类加载

    • 介绍
      在这里插入图片描述

    在这里插入图片描述
    在这里插入图片描述

    • 类加载过程
      在这里插入图片描述

    各阶段完成的任务
    在这里插入图片描述

    • 加载阶段
      在这里插入图片描述
    • 连接阶段—验证
      在这里插入图片描述
    • 连接阶段—准备
      在这里插入图片描述
    package com.reflection.classload_;
    /**
    * @author wzl
    * @version 1.0
    * 我们说明一个类加载的链接阶段-准备
    */
    public class ClassLoad02 {
    public static void main(String[] args) {
    }
    }
    class A{
    //属性-成员变量-字段
    //老韩分析类加载的链接阶段-准备 属性是如何处理
    
    //1. n1 是实例属性, 不是静态变量,因此在准备阶段,是不会分配内存
    //2. n2 是静态变量,分配内存 n2 是默认初始化 0 ,而不是 20
    //3. n3 是 static final 是常量, 他和静态变量不一样, 因为一旦赋值就不变 n3 = 30
    public int n1 = 10;
    public static int n2 = 20;
    public static final int n3 = 30;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 连接阶段—解析
      在这里插入图片描述
    • 初始化
      在这里插入图片描述
    package com.reflection.classload_;
    /**
     1. @author wzl
    
     2. @version 1.0
     3. 演示类加载-初始化阶段
    */
    public class ClassLoad03 {
    public static void main(String[] args) throws ClassNotFoundException {
    //1. 加载 B 类,并生成 B 的 class 对象
    //2. 链接 num = 0
    //3. 初始化阶段
    // 依次自动收集类中的所有静态变量的赋值动作和静态代码块中的语句,并合并
    /*
    clinit() {
    System.out.println("B 静态代码块被执行");
    //num = 300;
    num = 100;
    }
    合并: num = 100
    */
    //new B();//类加载
    //System.out.println(B.num);//100, 如果直接使用类的静态属性,也会导致类的加载
    //看看加载类的时候,是有同步机制控制
    /*
    protected Class loadClass(String name, boolean resolve)
    throws ClassNotFoundException
    {
    //正因为有这个机制,才能保证某个类在内存中, 只有一份 Class 对象
    synchronized (getClassLoadingLock(name)) {
    //....
    }
    }
    */
    B b = new B();
    }
    }
    class B {
    static {
    System.out.println("B 静态代码块被执行");
    num = 300;
    }
    static int num = 100;
    public B() {//构造器
    System.out.println("B() 构造器被执行");
    }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47

    通过反射获取类的结构信息

    • 第一组: java.lang.Class 类
      在这里插入图片描述
    package com.class_;
    
    import org.junit.Test;
    
    import javax.lang.model.element.NestingKind;
    import java.lang.annotation.Annotation;
    import java.lang.reflect.Constructor;
    import java.lang.reflect.Field;
    import java.lang.reflect.Method;
    
    /**
     * @Description
     * @autor wzl
     * @date 2022/8/19-14:46
     */
    public class ReflectionUtils_ {
        public static void main(String[] args) {
    
        }
    
        @Test
        public void test01() throws ClassNotFoundException {
            Class<?> cls = Class.forName("com.class_.Person");
            //getName:获取全类名
            System.out.println("全类名:"+cls.getName());
    
            //getSimpleName:获取简单类名
            System.out.println("简单类名"+cls.getSimpleName());
    
            //getFields:获取所有public修饰的属性,包括父类以及本类的
            Field[] fields = cls.getFields();
            for (Field field : fields) {
                System.out.println("本类以及父类的属性:" + field.getName());
            }
    
            //getDeclaredFields:获取本类中所有属性
            Field[] declaredFields = cls.getDeclaredFields();
            for (Field declaredField : declaredFields) {
                System.out.println("本类中所有属性:"+declaredField.getName());
            }
    
            //getMethods:获取所有public修饰的方法,包括本类以及父类的
            Method[] methods = cls.getMethods();
            for (Method method : methods) {
                System.out.println("本类以及父类的方法:"+method.getName());
            }
    
            //getDeclaredMethods:获取本类中所有方法
            Method[] declaredMethods = cls.getDeclaredMethods();
            for (Field declaredField : declaredFields) {
                System.out.println("本类中所有方法:"+declaredField.getName());
            }
    
            //getConstructors:获取所有的public修饰的构造器,父类的获取不到
            Constructor<?>[] constructors = cls.getConstructors();
            for (Constructor<?> constructor : constructors) {
                System.out.println("本类的构造器:"+constructor.getName());
            }
    
            //getDeclaredConstructors:获取本类中所有的构造器
            Constructor<?>[] declaredConstructors = cls.getDeclaredConstructors();
            for (Constructor<?> declaredConstructor : declaredConstructors) {
                System.out.println("本类中所有构造器:"+declaredConstructor.getName());
            }
    
            //getPackage:以package形式返回包信息
    
            System.out.println(cls.getPackage());
    
            //getSuperClass:以class形式返回父类信息
            Class<?> superclass = cls.getSuperclass();
            System.out.println("父类的class对象:"+superclass);
    
            //getInterfaces:以class[]形式返回接口信息
            Class<?>[] interfaces = cls.getInterfaces();
            for (Class<?> anInterface : interfaces) {
                System.out.println("接口信息:"+anInterface);
            }
    
            //getAnnotations:以Annotation[]形式返回注解信息
            Annotation[] annotations = cls.getAnnotations();
            for (Annotation annotation : annotations) {
                System.out.println("注解信息:"+annotation);
            }
        }
    }
    
    class A {
        public String hobby;
    
        public void hi() {
        }
    
        public A() {
        }
        public A(String name){
    
        }
    }
    
    interface IA{}
    interface IB{}
    
    @Deprecated
    class Person extends A implements IA,IB{
        //属性
        public String name;
        protected int age;
        String job;
        private double sal;
    
        private Person(String name,int age){
    
        }
    
        public Person() {
        }
    
        public Person(String name) {
            this.name = name;
        }
    
        //方法
        public void m1() {
    
        }
    
        protected void m2() {
    
        }
    
        void m3() {
    
        }
    
        private void m4() {
    
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 第二组: java.lang.reflect.Field 类
    • 第三组:java.lang.reflect.Method 类
    • 第四组: java.lang.reflect.Constructor 类
      在这里插入图片描述
      在这里插入图片描述
    package com.class_;
    
    import org.junit.Test;
    
    import javax.lang.model.element.NestingKind;
    import javax.xml.bind.annotation.XmlList;
    import java.lang.annotation.Annotation;
    import java.lang.reflect.Constructor;
    import java.lang.reflect.Field;
    import java.lang.reflect.Method;
    
    /**
     * @Description
     * @autor wzl
     * @date 2022/8/19-14:46
     */
    public class ReflectionUtils_ {
        public static void main(String[] args) {
    
        }
    
        @Test
        public void test02() throws ClassNotFoundException {
            Class<?> cls = Class.forName("com.class_.Person");
            //getDeclaredFields:获取本类中所有属性
            //规定 说明: 默认修饰符 是 0 , public 是 1 ,private 是 2 ,protected 是 4 , static 是 8 ,final 是 16
            Field[] declaredFields = cls.getDeclaredFields();
            for (Field declaredField : declaredFields) {
                System.out.println("本类中所有属性:"+declaredField.getName()
                +"该属性的修饰符值:"+declaredField.getModifiers()
                +"该属性的类型:"+declaredField.getType());
            }
    
            //getDeclaredMethods:获取本类中所有方法
            Method[] declaredMethods = cls.getDeclaredMethods();
            for (Method declaredMethod : declaredMethods) {
                System.out.println("本类中所有方法:"+declaredMethod.getName()
                +"该方法的访问修饰符值:"+declaredMethod.getModifiers()
                +"该方法返回类型:"+declaredMethod.getReturnType());
                //输出当前这个方法的形参数组情况
    
                Class<?>[] parameterTypes = declaredMethod.getParameterTypes();
                for (Class<?> parameterType : parameterTypes) {
                    System.out.println("该方法的形参类型:"+parameterType);
                }
            }
    
            //getDeclaredConstructors:获取本类中所有构造器
            Constructor<?>[] declaredConstructors = cls.getDeclaredConstructors();
            for (Constructor<?> declaredConstructor : declaredConstructors) {
                System.out.println("======");
                System.out.println("本类的所有构造器:"+declaredConstructor.getName());
    
                Class<?>[] parameterTypes = declaredConstructor.getParameterTypes();
                for (Class<?> parameterType : parameterTypes) {
                    System.out.println("该构造器的形参类型:"+parameterType);
                }
            }
    
    
        }
    }
    
    class A {
        public String hobby;
    
        public void hi() {
        }
    
        public A() {
        }
        public A(String name){
    
        }
    }
    
    interface IA{}
    interface IB{}
    
    @Deprecated
    class Person extends A implements IA,IB{
        //属性
        public String name;
        protected static int age;
        String job;
        private double sal;
    
        private Person(String name,int age){
    
        }
    
        public Person() {
        }
    
        public Person(String name) {
            this.name = name;
        }
    
        //方法
        public void m1(String name,int age,double sal) {
    
        }
    
        protected void m2() {
    
        }
    
        void m3() {
    
        }
    
        private void m4() {
    
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115

    通过反射创建对象

    • 介绍
      在这里插入图片描述
    • 案例1----反射构造对象

    反射可以使用私有构造器创建对象

    package com.fanshe;
    
    import javax.jws.soap.SOAPBinding;
    import java.lang.reflect.Constructor;
    import java.lang.reflect.Field;
    import java.lang.reflect.InvocationTargetException;
    import java.net.URL;
    
    /**
     * @Description
     * @autor wzl
     * @date 2022/8/19-15:36
     * 通过反射创建对象实例
     */
    public class Create_ {
        public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
    
            //1.先获取User类的Class对象
            Class<?> cls = Class.forName("com.fanshe.User");
            //2.通过public 无参构造器创建对象
            Object o = cls.newInstance();
            System.out.println(o);
    
            //3.通过public 有参构造器创建对象
    
            /*
            constructor 对象就是
            public User(String name) {//public 的有参构造器
            this.name = name;
            }
             */
            //3.1 先得到对应构造器
            Constructor<?> constructor = cls.getConstructor(String.class);
            //3.2 创建实例,并传入实参
            Object temp = constructor.newInstance("hahn");
            System.out.println(temp);
    
            //4.通过非public 有参构造器创建实例
            //4.1 得到private的构造器对象
            Constructor<?> declaredField = cls.getDeclaredConstructor(int.class, String.class);
    
            //4.2 创建实例
            //暴破【暴力破解】 , 使用反射可以访问 private 构造器/方法/属性, 反射面前,都是纸老虎
            declaredField.setAccessible(true);
            Object user = declaredField.newInstance(100, "dddd");
            System.out.println("user" + user);
    
    
        }
    }
    
    class User {
        private int age = 10;
        private String name = "wzl";
    
        public User() {
        }//无参 public
    
        public User(String name) { //有参 public
    
            this.name = name;
        }
    
        private User(int age, String name) {
            this.age = age;
            this.name = name;
        }//有参 private
    
        @Override
        public String toString() {
            return "User{" +
                    "age=" + age +
                    ", name='" + name + '\'' +
                    '}';
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 案例2----反射访问类中的属性
      在这里插入图片描述
    package com.fanshe;
    
    import java.lang.reflect.Field;
    
    /**
     * @Description
     * @autor wzl
     * @date 2022/8/19-15:56
     */
    public class Create01_ {
        public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchFieldException {
    
            Class<?> student = Class.forName("com.fanshe.Student");
            //2.创建对象
            Object o = student.newInstance();
            System.out.println(o.getClass());//class com.fanshe.Student
            //3.使用反射得到age属性对象
            Field age = student.getField("age");
            age.set(o,22);
            System.out.println(o);//Student[age=22,name=null]
            System.out.println(age.get(o));//返回age属性的值
    
            //4.使用反射操作name属性
            Field name = student.getDeclaredField("name");
            //对name进行爆破,可以操作private属性
            name.setAccessible(true);
            name.set(o,"李明");
            name.set(null,"小红");//name是static属性,O也可以写成null
            System.out.println(o);//Student[age=22,name=小红]
            System.out.println(name.get(o));//获取属性值
            System.out.println(name.get(null));//获取属性值,name必须是static
    
    
    
        }
    }
    
    class Student {
        public int age;
        private static String name;
    
        public Student() {
        }
    
        @Override
        public String toString() {
            return "Student[age="+age+",name="+name+"]";
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 案例3----反射获取方法
      在这里插入图片描述
    package com.fanshe;
    
    import java.lang.reflect.Field;
    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;
    
    /**
     * @Description
     * @autor wzl
     * @date 2022/8/19-16:08
     */
    public class create03_ {
        public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
            //1.获取boss类对应的class对象
            Class<?> bossCLs = Class.forName("com.fanshe.Boss");
            //2.创建对象
            Object o = bossCLs.newInstance();
            //3.调用 public hi()
            //Method hi = bossCLs.getMethod("hi", String.class);//ok
    
            //3.1得到hi方法的对象
            Method hi1 = bossCLs.getDeclaredMethod("hi", String.class);//ok
            //3.2调用hi方法
            hi1.invoke(o,"你好,世界");
    
            //4.调用private static 方法
            //4.1 得到say方法的对象
            Method say = bossCLs.getDeclaredMethod("say", int.class, String.class, char.class);
            //4.2 因为 say 方法是 private, 所以需要暴破,原理和前面讲的构造器和属性一样
            say.setAccessible(true);
            //4.3因为 say 方法是 static 的,还可以这样调用 ,可以传入 null
            System.out.println(say.invoke(o, 22, "你好", '男'));//22你好男
            System.out.println(say.invoke(null, 33, "你好", '女'));//33你好女
    
            //在反射中,如果方法有返回值,统一返回 Object , 但是他运行类型和方法定义的返回类型一致
            Object invoke = say.invoke(null, 200, "王五", '男');
            System.out.println("invoke运行类型"+invoke.getClass());//invoke运行类型class java.lang.String
    
            Method m1 = bossCLs.getDeclaredMethod("m1");
            Object invoke1 = m1.invoke(o);
            System.out.println("invoke1的运行类型"+invoke1.getClass());//invoke1的运行类型class com.fanshe.Monster
    
    
        }
    }
    
    class Monster {
    }
    
    class Boss {
        public int age;
        private static String name;
    
        public Boss() {
        }
    
        public Monster m1() {
            return new Monster();
        }
    
        private static String say(int n, String s, char c) {
            return n + "" + s + "" + c;
        }
    
        public void hi(String s) {
            System.out.println("hi" + s);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68

    练习1

    在这里插入图片描述

    package com.fanshe;
    
    import java.lang.reflect.Field;
    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;
    
    /**
     * @Description
     * @autor wzl
     * @date 2022/8/19-16:22
     */
    public class homework1 {
        public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchFieldException, NoSuchMethodException, InvocationTargetException {
            //1.
            Class<?> cls = Class.forName("com.fanshe.PrivateTest");
            //2.
            Object o = cls.newInstance();
    
            //3.
            Field name = cls.getDeclaredField("name");
            name.setAccessible(true);
            //4.
            name.set(o,"李明");
            //5.
            Method getName = cls.getMethod("getName");
            //6.
            System.out.println(getName.invoke(o));
    
        }
    
    }
    class PrivateTest{
        private String name="hellokityy";
        //默认无参构造器
        public String getName(){
            return name;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38

    练习2

    在这里插入图片描述

    package com.fanshe;
    
    import java.lang.reflect.Constructor;
    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;
    
    /**
     * @Description
     * @autor wzl
     * @date 2022/8/19-16:28
     */
    public class homework2 {
        public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
            //1. 得到file类的class对象
            Class<?> fileCls = Class.forName("java.io.File");
            //2.得到所有构造器
            Constructor<?>[] declaredConstructors = fileCls.getDeclaredConstructors();
            for (Constructor<?> declaredConstructor : declaredConstructors) {
                System.out.println("file构造器:"+declaredConstructor);
            }
            //3.创建file对象 public java.io.File(java.lang.String)
            Constructor<?> declaredConstructor = fileCls.getDeclaredConstructor(String.class);
    
            String filePath="D:\\hi.txt";
            //创建file对象
            Object o = declaredConstructor.newInstance(filePath);
    
            //4.得到createNewFile方法的对象
            Method createNewFile = fileCls.getMethod("createNewFile");
            createNewFile.invoke(o);
    
            //file的运行类型
            System.out.println(o.getClass());
            System.out.println("创建文件成功"+filePath);
    
    
    
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
  • 相关阅读:
    “程序包com.sun.tools.javac.util不存在” 问题解决
    Python绘图系统24:绘图类型和坐标映射的关系
    程序员追星 - Hal Abelson
    Windows安装nvm【node.js版本管理工具】
    SpringMVC程序开发
    剑指 Offer 33. 二叉搜索树的后序遍历序列
    0001 - Hadoop及其大数据生态圈
    BFD基本概念与接口、静态路由联动
    Linux环境下安装Node.js
    微信小程序开发学习——顺序、选择、循环、数学函数
  • 原文地址:https://blog.csdn.net/qq_38716929/article/details/126417505