Java从入门到精通23==》类加载器、反射、反射练习

Java从入门到精通23==》类加载器、反射、反射练习

2023.8.20

文章目录

  • Java从入门到精通23==》类加载器、反射、反射练习
    • 一、类加载器
    • 二、反射
      • 1、什么是反射
      • 2、Class类
        • 1.什么是Class类
        • 2.如何使用
      • 3、通过反射获取构造方法并使用
      • 4、通过反射获取成员变量进行赋值与获取值操作
      • 5、通过反射获取成员方法并使用
    • 三、反射练习

一、类加载器

在Java中,类是通过类加载器加载的。类加载器的任务是将Java字节码转换为在Java虚拟机中可以使用的运行时数据结构。以下是类加载器加载类的步骤:

  1. 加载:类加载器通过使用类的全限定名来查找该类的二进制字节码文件,并将其读入内存。当类加载器找到类文件后,它会创建一个表示该类的对象(称为Class对象)并将其放入方法区中。
  2. 链接:链接是将类的二进制数据合并到JRE中的运行时状态中的过程。链接分为三个阶段:
    • 验证:验证确保类文件的字节流包含的信息符合Java虚拟机规范,并且没有被篡改。这个过程是为了保证JVM的安全性不受到威胁,是类加载过程中的一个非常重要的部分。
    • 准备:在准备阶段,类变量被赋予默认值。这是因为在代码执行之前,需要保证所有类变量都已经被初始化。
    • 解析:解析阶段是将符号引用替换为直接引用的过程。由于Java虚拟机运行的是字节码,因此需要将类、方法和字段等符号引用解析为直接引用。
  3. 初始化:初始化阶段是类加载过程中的最后一步。在这个阶段,执行静态初始化代码块和赋值静态变量的操作。在此之后,类将被视为初始化完成,并且可以被Java虚拟机使用。

二、反射

1、什么是反射

是指在程序运行时,动态地获取类的信息、分析类的信息并操作对象的信息的能力。通过反射,可以在运行时获取类的成员变量、方法、构造函数等信息,还可以创建对象、调用方法、动态修改类的属性和方法等。

2、Class类

1.什么是Class类

Class类是一个Java内置的类,用于描述其他类的结构和行为

2.如何使用

因为没有构造方法,所以使用内部方法创建对象
方式一:
通过Object类中的getClass()方法
代码示例:

 Class studentClass1 = student.getClass();

方式二:
通过 类名.class 获取到字节码文件对象
代码示例:

 Class studentClass2=Student.class;

方式三:
通过Class类中的方法
代码示例:

 try {
            Class studentClass3=Class.forName("Class类的创建对象.Student");
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        }

3、通过反射获取构造方法并使用

代码示例:

		//获取Class对象
        Class calss_studebt = Class.forName("通过反射获取构造方法并使用.Student");
        //获取Claa对象的构造器(非私有)
        Constructor constructor = calss_studebt.getConstructor(int.class, String.class);
        System.out.println(constructor);
        //调用构造器
        Student student1 = (Student) constructor.newInstance(26, "sdasda");
        System.out.println(student1.toString());
        //获取Class对象的构造器(私有)
        Constructor constructor1 = calss_studebt.getDeclaredConstructor();
        System.out.println(constructor1);
        //调用私有构造器,创建对象
        Student student2 = (Student) constructor1.newInstance();
        System.out.println(student2.toString());

结果展示:
Java从入门到精通23==》类加载器、反射、反射练习_第1张图片

4、通过反射获取成员变量进行赋值与获取值操作

代码示例:

       //获取Class对象
        Class class_student = Class.forName("获取成员变量进行赋值与获取值操作.Student");
        //获取构造方法
        Constructor constructor = class_student.getConstructor(int.class, String.class);
        //创建对象
        Student student = (Student)constructor.newInstance(20, "孙悟空");
        System.out.println(student);
        //获取成员变量(这里的成员变量为私有的)
        Field field_name = class_student.getDeclaredField("name");
        Field field_age = class_student.getDeclaredField("age");
        //”修改“成员变量的权限(暴力破解)
        field_age.setAccessible(true);field_name.setAccessible(true);
        //取值
        System.out.println(field_age.get(student));
        System.out.println(field_name.get(student));
        //赋值
        field_age.set(student,25);
        field_name.set(student,"猪八戒");
        System.out.println(student);

结果展示:
Java从入门到精通23==》类加载器、反射、反射练习_第2张图片

5、通过反射获取成员方法并使用

代码示例:
.

       //获取Class对象
        Class class_student =Class.forName("通过反射获取成员方法并使用.Student");
        //获取构造方法
        Constructor<Student> constructor = class_student.getConstructor(int.class, String.class);
        //创建对象
        Student student = constructor.newInstance(28,"花蝴蝶");
        //获取方法
        Method method_getName = class_student.getMethod("getName");
        System.out.println(method_getName);
        Method method_setName = class_student.getMethod("setName",String.class);
        System.out.println(method_setName);
        //获取私有方法
        Method method_getAge= class_student.getDeclaredMethod("getAge");
        System.out.println(method_getAge);
        Method method_setAge= class_student.getDeclaredMethod("setAge",int.class);
        System.out.println(method_setAge);
        //绑定方法给对象并使用
        System.out.println(student);
        method_setName.invoke(student,"沙和尚");
        System.out.println(method_getName.invoke(student));
        method_setAge.invoke(student,120);
        System.out.println(method_getAge.invoke(student));
        System.out.println(student);

结果展示:
Java从入门到精通23==》类加载器、反射、反射练习_第3张图片
这里的Student类是一个标准的JavaBean类,一些方法因为需要被设为私有

package 通过反射获取成员方法并使用;

class Student {
    protected int age;
    protected String name;

    protected Student() {
    }

    protected int getAge() {
        return age;
    }

    protected void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Student{" +
                "age=" + age +
                ", name='" + name + '\'' +
                '}';
    }

    public Student(int age, String name) {
        this.age = age;
        this.name = name;
    }
}

三、反射练习

泛型擦除

package 泛型擦除;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;

public class Demo {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        //创建一个只能存Integer类型的数组
        ArrayList<Integer> list = new ArrayList<>();
        list.add(11);
        list.add(13);
        list.add(15);
        //获取Class对象
        Class<?> class_Arraylist = Class.forName("java.util.ArrayList");
        //通过对象获取add方法,因为泛型值对编译起作用
        Method class_add = class_Arraylist.getMethod("add",Object.class);
        //这个时候就可以添加String类型的数据
        class_add.invoke(list,"lllll");
        System.out.println(list);
    }
}

Java从入门到精通23==》类加载器、反射、反射练习_第4张图片

你可能感兴趣的:(java,开发语言,深度学习)