当前位置:网站首页>反射机制篇

反射机制篇

2022-08-09 21:54:00 Martin__Liu

一. 反射机制


2.1 反射快速入门


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

各文件层次结构

在这里插入图片描述

re.properties配置文件:

classfullpath=com.hspedu.Cat
method=hi

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);
    }
    
}

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);

    }

}

仿真结果:

"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

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

classfullpath=com.hspedu.Cat
method=cry

修改 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



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));   //传统写法 对象.成员变量

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);
    }

}
//具体代码:

        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的构造器
//仿真结果:

=========  java.lang.reflect.Constructor  ================
public com.hspedu.Cat()
public com.hspedu.Cat(java.lang.String)


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));
    }


}

仿真结果:

"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


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));
    }



}

"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


二. 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());
        

    }

}

"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


不同的类通过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());


    }

}

"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

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());



    }

}

"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


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

    }

}


"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


实例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());

    }
}

"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



实例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 + '\'' +
                '}';
    }
}

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));
        }


    }
}

"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


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());



    }


}

"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


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);


    }

}

"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


三. 类加载


  • 反射机制是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~");


        }




    }

}

在这里插入图片描述


类加载流程图:

类加载流程图



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

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


参考链接


五. 反射相关类


参考链接


六. class类常用方法


参考链接

原网站

版权声明
本文为[Martin__Liu]所创,转载请带上原文链接,感谢
https://blog.csdn.net/qq_25355771/article/details/126218081