• 反射机制篇


    一. 反射机制


    2.1 反射快速入门


    • (1). 根据配置文件调用源代码的信息,在不更改源代码,只需要更改配置文件,就可以实现功能的实现。
    • (2). 这样的需求在学习框架时特别多(开闭原则:不修改源代码,扩容功能)

    各文件层次结构

    在这里插入图片描述

    re.properties配置文件:

    classfullpath=com.hspedu.Cat
    method=hi
    
    • 1
    • 2

    Cat类猫:

    package com.hspedu;
    
    public class Cat {
        private String name = "招财猫";
        private String cry = "喵喵喵";
        public void hi(){
            //常用方法
            System.out.println("hi" + name);
        }
        
        public void cry(){
            System.out.println("cry" + cry);
        }
        
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    Java源代码:

    package com.hspedu.reflection.question;
    
    import com.hspedu.Cat;
    
    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;
    
    public class ReflectionQuetion {
        public static void main(String[] args) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
    
        //根据配置文件re.properties指定信息,创建Cat对象并调用方法hi
        //1.使用传统方法  使用new创造对象
            Cat cat = new Cat();
            cat.hi();
         @SuppressWarnings({"all"})
        //2.使用配置文件读取配置信息
            Properties properties = new Properties();
            properties.load(new FileInputStream("src\\re.properties"));
    
            String classfullpathName = properties.get("classfullpath").toString();
            String methodName = properties.get("method").toString();
            System.out.println("classfullpath=" + classfullpathName);
            System.out.println("method=" + methodName);
            
        //这里的classfulpath 还有 method 读取的仅仅是配置文件的字符串信息,而非真正的类。
        //目前的策略,没有合适的可以解决这样的问题。只能通过:配置信息 + 反射机制 解决这样的问题。     
            
        //3.利用反射机制创建对象
            // (1).加载类,返回class类型的对象clc
            Class clc = Class.forName(classfulpathName);	//注意了,这里没有双引号,直接采用的名字
            
            // (2).通过clc类创建类的对象实例
            Object o = clc.newInstance();
            System.out.println("o的运行类=" + o.getClass());
            
            // (3).通过clc得到方法对象 
            Method method = clc.getMethod(methodName);
            method.invoke(o);
    
        }
    
    }
    
    
    • 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

    仿真结果:

    "C:\Program Files\Java\jdk1.8.0_152\bin\java.exe" "-javaagent:D:\软件下载\idea\idea\IntelliJ IDEA 2021.1\lib\idea_rt.jar=52611:D:\软件下载\idea\idea\IntelliJ IDEA 2021.1\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_152\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\rt.jar;E:\刘建成\java\project\Pro\out\production\Pro" com.hspedu.reflection.question.ReflectionQuetion
    hi招财猫
    classfullpath=com.hspedu.Cat
    method=hi
    o的运行类=class com.hspedu.Cat
    =====================
    hi招财猫
    
    Process finished with exit code 0
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    修改 re.properties 配置文件,而其他的不要动:

    classfullpath=com.hspedu.Cat
    method=cry
    
    • 1
    • 2

    修改 re.properties 配置文件后的仿真结果:

    "C:\Program Files\Java\jdk1.8.0_152\bin\java.exe" "-javaagent:D:\软件下载\idea\idea\IntelliJ IDEA 2021.1\lib\idea_rt.jar=53025:D:\软件下载\idea\idea\IntelliJ IDEA 2021.1\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_152\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\rt.jar;E:\刘建成\java\project\Pro\out\production\Pro" com.hspedu.reflection.question.ReflectionQuetion
    hi招财猫
    classfullpath=com.hspedu.Cat
    method=cry
    o的运行类=class com.hspedu.Cat
    =====================
    cry喵喵喵
    
    Process finished with exit code 0
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10


    2.2 反射机制

      1. 反射机制允许程序在执行期间借助于Reflection API取得任何类的内部信息(比如:成员变量,构造器,成员方法等等),并能操作对象的属性及方法。反射再设计模式和框架底层都会用到。
      1. 加载完类之后,在堆之中就会产生一个Class类型的对象,这个对象包含了类的完整的结构信息。通过这个镜子得到类的结构,所以,形象的称之为:反射
      1. 优点:可以动态的创建和使用对象。没有反射技术,框架技术就失去了底层支撑。
      1. 缺点:使用反射基本是解释执行,对执行速度有影响。

    原理图

    • java.lang.Class: 代表一个类,Class对象表示某个类加载后再堆中的对象
    • java.lang.reflect.Method: 代表类的方法,Method对象表示某个类的方法
    • java.lang.reflect.Field: 代表类的成员变量,Field对象表示某个类的成员变量
    • java.lang.reflect.Constructor: 代表类的构造方法,Constructor对象表示构造器
      这些类在java.lang.reflec

    java.lang.reflect.Field的使用:

     /**
             * java.lang.reflect.Field的使用:
             */
    
            System.out.println("=========  getField  ================");
            //得到name字段:
            Field nameField = clc.getField("age");  //getFiled不能得到私有的属性
            System.out.println(nameField.get(o));   //传统写法 对象.成员变量
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    java.lang.reflect.Constructor的使用:

    // Cat 修改版本
    
    package com.hspedu;
    
    public class Cat {
        private String name = "招财猫";
        private String cry = "喵喵喵";
        public int age = 10;
    	//增加 Cat 的构造器函数
        public Cat(String name){
            this.name = name;
        }
        //Cat没有了默认的无参构造函数,得重新建立一个无参数的构造函数
        public Cat(){
    
        }
    
        public void hi(){
            //常用方法
            System.out.println("hi" + name);
        }
    
        public void cry(){
            System.out.println("cry" + cry);
        }
    
    }
    
    • 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
    //具体代码:
    
            System.out.println("=========  java.lang.reflect.Constructor  ================");
            //java.lang.reflect.Constructor: 代表类的构造方法,Constructor对象表示构造器
            Constructor constructor = clc.getConstructor(); //()中可以指定构造器的参数类型,返回无参构造器
            System.out.println(constructor);
    
            Constructor constructor1 = clc.getConstructor(String.class);    //这里传入的String.class就是String类的class对象
            System.out.println(constructor1);       //输出带形式参数String的构造器
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    //仿真结果:
    
    =========  java.lang.reflect.Constructor  ================
    public com.hspedu.Cat()
    public com.hspedu.Cat(java.lang.String)
    
    • 1
    • 2
    • 3
    • 4
    • 5


    2.3 反射和传统的方法时间对比


    2.3.1 时间复杂度对比


    时间对比源代码:

    package com.hspedu.reflection0;
    
    import com.hspedu.Cat;
    
    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;
    
    /**
     * //测试反射调用的性能和优化方案
     */
    
    public class Reflection02 {
        public static void main(String[] args) throws ClassNotFoundException, InvocationTargetException, InstantiationException, IllegalAccessException, NoSuchMethodException {
            m1();
            m2();
        }
    
        //传统方法来调用hi
        public static void m1(){
            Cat cat = new Cat();
            long start = System.currentTimeMillis();
            for(int i=0; i<90000000; i++){
                cat.hi();
            }
            long end = System.currentTimeMillis();
            System.out.println("传统 m1 方法来调用 hi 耗时=" + (end - start));
        }
    
    
        //反射机制调用方法
        public static void m2() throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
            Class<?> clc = Class.forName("com.hspedu.Cat");
            Object o = clc.newInstance();
            Method hi = clc.getMethod("hi");
            long start = System.currentTimeMillis();
            for(int i=0; i<90000000; i++){
                hi.invoke(o);
            }
            long end = System.currentTimeMillis();
            System.out.println("反射机制的 m2 方法来调用 hi 耗时=" + (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

    仿真结果:

    "C:\Program Files\Java\jdk1.8.0_152\bin\java.exe" "-javaagent:D:\软件下载\idea\idea\IntelliJ IDEA 2021.1\lib\idea_rt.jar=53251:D:\软件下载\idea\idea\IntelliJ IDEA 2021.1\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_152\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\rt.jar;E:\刘建成\java\project\Pro\out\production\Pro" com.hspedu.reflection0.Reflection02
    传统 m1 方法来调用 hi 耗时=10
    反射机制的 m2 方法来调用 hi 耗时=537
    
    Process finished with exit code 0
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    2.3.1 反射代码优化


    反射部分的代码调用优化:

    • MethodFieldConstructor对象都有setAccessible()方法
    • setAccessible()作用是启动和禁用访问安全检查的开关
    • 参数值为true表示反射的对象在使用时取消访问检查,提高反射效率。参数值为false表示反射的对象在使用时开启访问检查
    package com.hspedu.reflection0;
    
    import com.hspedu.Cat;
    
    import java.lang.reflect.Field;
    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;
    
    /**
     * //测试反射调用的性能和优化方案
     */
    
    public class Reflection02 {
        public static void main(String[] args) throws ClassNotFoundException, InvocationTargetException, InstantiationException, IllegalAccessException, NoSuchMethodException {
    
            m1();
            m2();
            m3();
        }
    
        //传统方法来调用hi
        public static void m1(){
            Cat cat = new Cat();
            long start = System.currentTimeMillis();
            for(int i=0; i<90000000; i++){
                cat.hi();
            }
            long end = System.currentTimeMillis();
            System.out.println("传统 m1 方法来调用 hi 耗时=" + (end - start));
        }
    
    
        //反射机制调用方法
        public static void m2() throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
            Class<?> clc = Class.forName("com.hspedu.Cat");
            Object o = clc.newInstance();
            Method hi = clc.getMethod("hi");
            long start = System.currentTimeMillis();
            for(int i=0; i<90000000; i++){
                hi.invoke(o);
            }
            long end = System.currentTimeMillis();
            System.out.println("反射机制的 m2 方法来调用 hi 耗时=" + (end - start));
        }
    
    
    
        //反射机制调用方法 + 性能优化
        public static void m3() throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
            Class<?> clc = Class.forName("com.hspedu.Cat");
            Object o = clc.newInstance();
            Method hi = clc.getMethod("hi");
    
            hi.setAccessible(true); //在反射方法调用时,取消访问检查
    
            long start = System.currentTimeMillis();
            for(int i=0; i<90000000; i++){
                hi.invoke(o);
            }
            long end = System.currentTimeMillis();
            System.out.println("反射机制的 m3 方法来调用 hi 耗时=" + (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
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    "C:\Program Files\Java\jdk1.8.0_152\bin\java.exe" "-javaagent:D:\软件下载\idea\idea\IntelliJ IDEA 2021.1\lib\idea_rt.jar=53289:D:\软件下载\idea\idea\IntelliJ IDEA 2021.1\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_152\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\rt.jar;E:\刘建成\java\project\Pro\out\production\Pro" com.hspedu.reflection0.Reflection02
    传统 m1 方法来调用 hi 耗时=10
    反射机制的 m2 方法来调用 hi 耗时=648
    反射机制的 m3 方法来调用 hi 耗时=329
    
    Process finished with exit code 0
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    二. class类


    2.1 Class类的基本介绍

    • 1.Class也是类,因此也继承了Object
    • 2.Class类对象不是new出来的,而是系统创建出来的
    • 3.对于某个类的Class类对象,在呢村中只有一份,因此类只加载一次
    • 4.每个类的实例都会记得自己是由哪个Class实例所生成
    • 5.通过Class可以完整地得到一个类的完整结构,通过一系列API
    • 6.Class对象是存放在堆的
    • 7.类的字节码二进制数据,是放在方法区的,有的地方称之为类的元数据

    2.1.1 Class类图


    在这里插入图片描述


    2.1.1 Class类加载方法


    • 通过ClassLoader 里面的loadClass()生成的Class对象

    传统的方法:

    在这里插入图片描述

    在这里插入图片描述

    反射的方法:
    在这里插入图片描述

    2.1.3 对于某个类的Class类对象,在中只有一份,因此类只加载一次


    同一个类通过Class类产生对象

    package com.hspedu.reflection0.class_;
    
    import com.hspedu.Cat;
    
    public class Class01 {
    
        public static void main(String[] args) throws ClassNotFoundException {
            //2. Class类对象不是new出来的,而是系统创建出来的
            //(1).传统的new对象
    
            //(2).反射方式
            Class clc1 = Class.forName("com.hspedu.Cat");
            Class clc2 = Class.forName("com.hspedu.Cat");
            System.out.println(clc1.hashCode());
            System.out.println(clc2.hashCode());
            
    
        }
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    "C:\Program Files\Java\jdk1.8.0_152\bin\java.exe" "-javaagent:D:\软件下载\idea\idea\IntelliJ IDEA 2021.1\lib\idea_rt.jar=53688:D:\软件下载\idea\idea\IntelliJ IDEA 2021.1\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_152\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\rt.jar;E:\刘建成\java\project\Pro\out\production\Pro" com.hspedu.reflection0.class_.Class01
    356573597
    356573597
    //这里表明,产生的是同一个对象
    Process finished with exit code 0
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    不同的类通过Class类产生对象

    package com.hspedu.reflection0.class_;
    
    import com.hspedu.Cat;
    
    public class Class01 {
    
        public static void main(String[] args) throws ClassNotFoundException {
            //2. Class类对象不是new出来的,而是系统创建出来的
            //(1).传统的new对象
    
            //(2).反射方式
            Class clc1 = Class.forName("com.hspedu.Cat");
            Class clc2 = Class.forName("com.hspedu.Cat");
            System.out.println(clc1.hashCode());
            System.out.println(clc2.hashCode());
    
    
            Class clc3 = Class.forName("com.hspedu.Dog");
            System.out.println(clc3.hashCode());
    
    
        }
    
    }
    
    
    • 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
    "C:\Program Files\Java\jdk1.8.0_152\bin\java.exe" "-javaagent:D:\软件下载\idea\idea\IntelliJ IDEA 2021.1\lib\idea_rt.jar=53697:D:\软件下载\idea\idea\IntelliJ IDEA 2021.1\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_152\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\rt.jar;E:\刘建成\java\project\Pro\out\production\Pro" com.hspedu.reflection0.class_.Class01
    356573597
    356573597
    1735600054
    //这里表明了,产生了不同的对象
    Process finished with exit code 0
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    Class方法和传统方法一起做对比,可看出采用Class的方法的特点

    package com.hspedu.reflection0.class_;
    
    import com.hspedu.Cat;
    
    public class Class01 {
    
        public static void main(String[] args) throws ClassNotFoundException {
            //2. Class类对象不是new出来的,而是系统创建出来的
            //(1).传统的new对象
    
            //(2).反射方式
            Class clc1 = Class.forName("com.hspedu.Cat");
            Class clc2 = Class.forName("com.hspedu.Cat");
            System.out.println("Class方法产生的Cat对象clc1:" + clc1.hashCode());
            System.out.println("Class方法产生的Cat对象clc2:" + clc2.hashCode());
    
    
            Class clc3 = Class.forName("com.hspedu.Dog");
            System.out.println("Class方法产生的Dog对象clc3:" + clc3.hashCode());
    
            Cat cat1 = new Cat();
            Cat cat2 = new Cat();
            System.out.println("传统方法对象cat1:" + cat1.hashCode());
            System.out.println("传统方法对象cat2:" + cat2.hashCode());
    
    
    
        }
    
    }
    
    
    • 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
    "C:\Program Files\Java\jdk1.8.0_152\bin\java.exe" "-javaagent:D:\软件下载\idea\idea\IntelliJ IDEA 2021.1\lib\idea_rt.jar=53728:D:\软件下载\idea\idea\IntelliJ IDEA 2021.1\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_152\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\rt.jar;E:\刘建成\java\project\Pro\out\production\Pro" com.hspedu.reflection0.class_.Class01
    Class方法产生的Cat对象clc1:356573597
    Class方法产生的Cat对象clc2:356573597
    Class方法产生的Dog对象clc3:1735600054
    传统方法对象cat1:21685669
    传统方法对象cat2:2133927002
    
    Process finished with exit code 0
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    2.1.4 每个类的实例都会记得自己是由哪个Class实例所生成



    2.1.5 通过Class可以完整地得到一个类的完整结构,通过一系列API


    在这里插入图片描述


    2.1.6 Class对象是存放在堆中的



    2.1.7 类的字节码二进制数据,放在方法区的,有的地方称为类的元数据


    Class类应用实例:


    实例1 —> 输出clc:

    package com.hspedu.reflection0.class_;
    
    /**
     * 演示Class类的常用方法
     *
     */
    
    
    public class Class02{
        public static void main(String[] args) throws ClassNotFoundException {
            String classAllPAth = "com.hspedu.Car";
    
            //获取读到的CAr类,对应的Class对象
            //表示不确定的Java类型
            Class<?> clc = Class.forName(classAllPAth);
    
            //输出clc
            System.out.println(clc);            //如果输出clc对象,是哪个类的Class对象,com.hspedu.Car
            System.out.println(clc.getClass()); //输出clc运行时类型:java.lang.Class
    
        }
    
    }
    
    
    
    • 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
    "C:\Program Files\Java\jdk1.8.0_152\bin\java.exe" "-javaagent:D:\软件下载\idea\idea\IntelliJ IDEA 2021.1\lib\idea_rt.jar=53840:D:\软件下载\idea\idea\IntelliJ IDEA 2021.1\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_152\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\rt.jar;E:\刘建成\java\project\Pro\out\production\Pro" com.hspedu.reflection0.class_.Class02
    class com.hspedu.Car
    class java.lang.Class
    
    Process finished with exit code 0
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    实例2 —> 得到包名:

    package com.hspedu.reflection0.class_;
    
    /**
     * 演示Class类的常用方法
     *
     */
    
    
    public class Class02{
        public static void main(String[] args) throws ClassNotFoundException {
            String classAllPAth = "com.hspedu.Car";
    
            //获取读到的CAr类,对应的Class对象
            //表示不确定的Java类型
            Class<?> clc = Class.forName(classAllPAth);
    
            //得到包名
            System.out.println(clc.getPackage().getName());
    
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    "C:\Program Files\Java\jdk1.8.0_152\bin\java.exe" "-javaagent:D:\软件下载\idea\idea\IntelliJ IDEA 2021.1\lib\idea_rt.jar=53855:D:\软件下载\idea\idea\IntelliJ IDEA 2021.1\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_152\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\rt.jar;E:\刘建成\java\project\Pro\out\production\Pro" com.hspedu.reflection0.class_.Class02
    com.hspedu
    
    Process finished with exit code 0
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    实例3 —> 其他方法:

    //为了显示更加方便,将Car类进行一定的更改
    package com.hspedu;
    
    public class Car {
        public String brand = "宝马";	//这里如果是私有属性,利用反射机制来获取对象属性会报错的,后面再看私有属性的获取
        public int price = 500000;
        public String color = "白色";
    
        @Override
        public String toString() {
            return "Car{" +
                    "brand='" + brand + '\'' +
                    ", price=" + price +
                    ", color='" + color + '\'' +
                    '}';
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    package com.hspedu.reflection0.class_;
    
    import com.hspedu.Car;
    
    import java.lang.reflect.Field;
    
    /**
     * 演示Class类的常用方法
     *
     */
    
    
    public class Class02{
        public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchFieldException {
            String classAllPAth = "com.hspedu.Car";
    
            //获取读到的CAr类,对应的Class对象
            //表示不确定的Java类型
            Class<?> clc = Class.forName(classAllPAth);
    
            //1. 得到包名
            System.out.println("得到包名" + clc.getPackage().getName());
    
            //2. 得到全类名
            System.out.println("得到全类名" + clc.getName());
    
            //3. 通过clc创建对象实例
            Car car = (Car) clc.newInstance();
            System.out.println(car);
    
            //4. 通过反射获取对象属性 brand
            Field brand = clc.getField("brand");
            System.out.println(brand.get(car)); //宝马
    
            //5. 通过反射给属性赋值
            brand.set(car,"奔驰"); //方法.对象。和传统的Java是反着的。
            System.out.println(brand.get(car)); //奔驰
    
            //6. 获取所有属性
            System.out.println("==========");
            Field[] fields = clc.getFields();
            for(Field f:fields){
                System.out.println(f.get(car));
            }
    
    
        }
    }
    
    
    • 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
    "C:\Program Files\Java\jdk1.8.0_152\bin\java.exe" "-javaagent:D:\软件下载\idea\idea\IntelliJ IDEA 2021.1\lib\idea_rt.jar=53886:D:\软件下载\idea\idea\IntelliJ IDEA 2021.1\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_152\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\rt.jar;E:\刘建成\java\project\Pro\out\production\Pro" com.hspedu.reflection0.class_.Class02
    得到包名com.hspedu
    得到全类名com.hspedu.Car
    Car{brand='宝马', price=500000, color='白色'}
    宝马
    奔驰
    ==========
    奔驰
    500000
    白色
    
    Process finished with exit code 0
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    2.2 获取Class类对象


    • 编译阶段:Class.forName()
    • 类加载阶段:类.class
    • 运行阶段:对象.getClass()

    package com.hspedu.reflection0.class_;
    
    import com.hspedu.Car;
    
    /**
     *
     * 演示得到Class对象的各种方式
     *
     */
    public class GetClass_ {
        /**
         * 1. 前提:已知一个类的全类名,且该类在类路径下,可通过Class类的静态方法
         *    forName()获取,可抛出ClassNotFoundException,实例:
         *    Class clc = Class.forName("java.lang.Cat");
         *    应用场景:多用于配置文件,读取类全路径,加载类
         *
         * 2. 前提:若已知具体的类,通过类的class获取,该方式最为安全可靠,程序性能最高
         *    实例:
         *    Class clc1 = Cat.class;
         *    应用场景:多用于参数传递,比如通过反射得到对应的构造器对象
         *
         *
         * 基本数据类型(int,char,boolean,float,double,byte,long,short)
         * 按照如下方式得到Class类对象:
         *      Class clc = 基本数据类型.class
         *
         *
         * 基本数据类型的包装类,可以通过.type得到Class类对象
         *      Class clc = 包装类.TYPE
         *
         *
         */
    
        public static void main(String[] args) throws ClassNotFoundException {
            //1. Class.forName
            String classALLPath = "com.hspedu.Car"; //通过读取配置文件获取到的
            Class<?> clc = Class.forName(classALLPath);
            System.out.println(clc);
    
            //2. 类.class。应用场景:参数传递
            Class clc1 = Car.class;
            System.out.println(clc1);
    
            //3. 通过: 对象.getClass(),应用场景,有对象实例
            Car car = new Car();
            Class clc2 = car.getClass();
            System.out.println(clc2);
    
            //4. 通过类加载器得到Class对象,一共有4种类加载器
            //(1).先得到类加载器car
            ClassLoader classLoader = car.getClass().getClassLoader();
            //(2).通过类加载器得到Class对象
            Class<?> clc3 = classLoader.loadClass(classALLPath);
            System.out.println(clc3);
    
    
            //clc clc1 clc2 clc3其实是同一个对象
            System.out.println("======clc clc1 clc2 clc3的hashcode()======");
            System.out.println(clc.hashCode());
            System.out.println(clc1.hashCode());
            System.out.println(clc2.hashCode());
            System.out.println(clc3.hashCode());
    
            //基本数据类型
            System.out.println("======基本数据类型:======");
            Class<Integer> integerClass = int.class;
            Class<Character> characterClass = char.class;
            Class<Boolean> booleanClass = boolean.class;
            System.out.println(integerClass);       //int
            System.out.println(characterClass);
    
    
            //基本数据类型对应的包装类
            System.out.println("======基本数据类型对应的包装类:======");
            Class<Integer> type1 = Integer.TYPE;
            Class<Character> type2 = Character.TYPE;
            System.out.println(type1);
            System.out.println(type2);
            System.out.println("type1的hashcode:" + type1.hashCode());
            System.out.println("包装类hashcode:" + integerClass.hashCode());
    
    
    
        }
    
    
    }
    
    
    • 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
    "C:\Program Files\Java\jdk1.8.0_152\bin\java.exe" "-javaagent:D:\软件下载\idea\idea\IntelliJ IDEA 2021.1\lib\idea_rt.jar=53967:D:\软件下载\idea\idea\IntelliJ IDEA 2021.1\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_152\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\rt.jar;E:\刘建成\java\project\Pro\out\production\Pro" com.hspedu.reflection0.class_.GetClass_
    class com.hspedu.Car
    class com.hspedu.Car
    class com.hspedu.Car
    class com.hspedu.Car
    ======clc clc1 clc2 clc3的hashcode()======
    356573597
    356573597
    356573597
    356573597
    ======基本数据类型:======
    int
    char
    ======基本数据类型对应的包装类:======
    int
    char
    type1的hashcode:1735600054
    包装类hashcode:1735600054
    
    Process finished with exit code 0
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    2.3 哪些类型有Class对象


      1. 外部类,成员内部类,静态内部类,局部内部类,匿名内部类
      1. interface接口
      1. 数组
      1. enum:枚举
      1. annotation:注解
      1. 基本数据类型
      1. void
    package com.hspedu.reflection0.class_;
    
    import java.io.Serializable;
    
    public class ALLTypeClas {
        public static void main(String[] args) {
    
            //外部类
            Class<String> cls1 = String.class;
            //接口
            Class<Serializable> cls2 = Serializable.class;
            //数组
            Class<Integer[]> cls3 = Integer[].class;
            //二维数组
            Class<float[][]> cls4 = float[][].class;
            //注解
            Class<Deprecated> cls5 = Deprecated.class;
            //枚举
            Class<Thread.State> cls6 = Thread.State.class;
            //long基本数据类型
            Class<Long> cls7 = long.class;
            //void
            Class<Void> cls8 = void.class;
            //Class
            Class<Class> cls9 = Class.class;
    
            System.out.println(cls1);
            System.out.println(cls2);
            System.out.println(cls3);
            System.out.println(cls4);
            System.out.println(cls5);
            System.out.println(cls6);
            System.out.println(cls7);
            System.out.println(cls8);
            System.out.println(cls9);
    
    
        }
    
    }
    
    
    • 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
    "C:\Program Files\Java\jdk1.8.0_152\bin\java.exe" "-javaagent:D:\软件下载\idea\idea\IntelliJ IDEA 2021.1\lib\idea_rt.jar=54011:D:\软件下载\idea\idea\IntelliJ IDEA 2021.1\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_152\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\rt.jar;E:\刘建成\java\project\Pro\out\production\Pro" com.hspedu.reflection0.class_.ALLTypeClas
    class java.lang.String
    interface java.io.Serializable
    class [Ljava.lang.Integer;
    class [[F
    interface java.lang.Deprecated
    class java.lang.Thread$State
    long
    void
    class java.lang.Class
    
    Process finished with exit code 0
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    三. 类加载


    • 反射机制是java实现动态语言的关键,也就是通过反射实现类动态加载。

      • 静态加载:编译时加载相关的类,如果没有则报错,依赖性太强

      • 动态加载:运行时加载需要的类,如果运行时不用该类,即使不存在该类,则不报错,降低了依赖性

    静态加载和动态加载对比的代码:

    package com.hspedu.reflection0.class_;
    
    import com.hspedu.Dog;
    
    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;
    import java.util.Scanner;
    
    public class ClassLoad_ {
        public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
            Scanner scanner = new Scanner(System.in);
    
            System.out.println("请输入key");
    
            String key = scanner.next();
    
            switch(key){
                case "1":
                    Dog dog = new Dog();
                    dog.cry();
                    dog.laugh();    //Dog里面没有这个类。编译时,如果有问题,则会报错,
                    break;
                case "2": //文件夹中没有Person这个类,编译时没有报错。在运行时,如果用到Person类,发现没有才会报错。
                    Class cls = Class.forName("Person");    //运行时,就算没有Person,只要不用他,是不会报错的。
                    Object o = cls.newInstance();
                    Method m = cls.getMethod("hi");
                    m.invoke(o);
                    System.out.println("ok~");
                    break;
                default:
                    System.out.println("do nothing~");
    
    
            }
    
    
    
    
        }
    
    }
    
    
    • 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

    在这里插入图片描述


    类加载流程图:

    类加载流程图



    • 类加载的各个阶段
      • JVM在该阶段的主要目的是将字节码从不同的数据源(可能是class文件、也可能是jar包,甚至网络)转换为二进制字节流加载到内存中,并生成一个代表该类的java.lang.Class对象
    • 连接阶段
      • 验证:
        • 1.目的是为了确保Class文件的字节流中包含的信息符合当前虚拟机的要求,姑且不会危害虚拟机自身的安全。
        • 2.包括:文件格式验证(是否以魔数oxcafebabe开头)、元数据验证,字节码验证和符号引用验证
        • 3.可以考虑使用 -Xverify:none 参数来关闭大部分的类验证措施,缩短虚拟机类加载的时间。
      • 准备:
      • 解析

    四. 反射获取类的结构信息


    参考链接


    五. 反射相关类


    参考链接


    六. class类常用方法


    参考链接

  • 相关阅读:
    刚办的手机号码为什么停机?那文章赶快了解一下吧。
    自定义MVC框架实现
    自学网络编程第一天- HTTP基础:基础原理、Request请求、Response应答
    国内唯一|阿里云入选 Gartner 应用性能监控与可观测魔力象限
    【知网稳定检索】第三届文化、设计与社会发展国际学术会议(CDSD 2023)
    图数据挖掘!使用图分析+AI进行保险欺诈检测
    安装chrome对应驱动
    自动化平台测试开发方案(详解自动化平台开发)
    python-(6-3-1)爬虫---requests入门
    【脏读、脏写、不可重复读、幻读】数据库数据并发产生的问题
  • 原文地址:https://blog.csdn.net/qq_25355771/article/details/126218081