Java学习笔记------反射机制(八)

文章详细介绍了Java中的反射机制,包括通过Class.forName(),类名.class,对象.getClass()三种方式获取Class对象,以及如何利用反射获取构造方法、成员变量和成员方法。此外,还阐述了Java代码从编写到运行的四个阶段,强调了类加载器和字节码文件在内存中的处理。反射在动态调用方法、访问私有成员等方面具有重要作用。
摘要由CSDN通过智能技术生成

该学习笔记是根据《黑马程序员Java零基础视频教程》和《黑马程序员JavaWeb全套基础教程,java web从入门到项目实战(IDEA版javaweb)》总结出来的。

一. 反射机制简单介绍

  1. 反射就是加载类,并允许以编程的方式解剖类中的各种成分(成员变量、成员方法、构造方法)。换句话说:反射允许对成员变量、成员方法和构造方法的信息进行编程访问。
    反射
  2. 获取字节码文件对象(获取Class对象)的三种方式
    三种方法
public class Test {
    public static void main(String[] args) throws ClassNotFoundException {
        // 第一种方式 Class.forName(全类名)最为常用。多用于配置文件,将全类名定义在配置文件中,读取文件,加载类。
        Class clazz1 = Class.forName("com.itheima.demo7.Student");
        System.out.println(clazz1);

        // 第二种方式 类名.class  一般是当做参数进行传递
        Class clazz2 = Student.class;
        System.out.println(clazz2);
        System.out.println(clazz1==clazz2); //这两种方式获取的对象是一模一样的

        // 第三种方式 对象.getClass()   当我们已经有了这个类的对象时,才可以使用
        Student stu = new Student();
        Class clazz3 = stu.getClass();
        System.out.println(clazz3);
        System.out.println(clazz1==clazz3);
        // 以上三种方式获取的CLass对象是一模一样的。

    }
}

class Student{
    String name;
    int age;

    public Student() {
    }

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
}
/*
输出:
class com.itheima.demo7.Student
class com.itheima.demo7.Student
true
class com.itheima.demo7.Student
true
*/

二. Java代码在计算机中经历的阶段

反射机制的实现

  1. 第一步:首先编写java代码Student.java,该代码中存在成员变量、成员方法、构造方法;
  2. 第二步:利用工具javac将Student.java代码编译成计算机能理解的机器语言,此过程生成一个字节码文件"Student.class"。无论是java代码还是class文件,它都存放于硬盘上,并没有进内存。
  3. 第三步:利用类加载器ClassLoader将硬盘上的字节码文件"Student.class"加载到JVM内存中,并生成一个CLass对象来描述字节码文件"Student.class"。该Class对象中有成员变量、构造方法、成员方法,我们将Class对象的成员变量封装为Filed对象;将构造方法封装为Constructor对象;将成员方法封装为Method对象。由于成员变量、成员方法、构造方法的数量通常不唯一,因此我们得到的是成员变量对象的数组(Filed对象的数组)、构造方法对象的数组(Constructor对象的数组)、成员方法对象的数组(Method对象的数组)
  4. 第四步:创建Student对象,运行代码。
  5. 注意点:同一个字节码文件(*.class)在一次程序运行过程中,只会被加载一次,无论通过那种方式获取的Class对象都是同一个。

三. 利用反射获取构造方法

获取构造方法

public class Test {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException {
        // 获取class字节码文件的对象
        Class clazz1 = Class.forName("com.itheima.demo7.Student");
        // 获取public修饰的构造方法
        Constructor[] cons = clazz1.getConstructors();
        System.out.println(Arrays.toString(cons));
        // 获取所有的构造方法
        Constructor[] dcs = clazz1.getDeclaredConstructors();
        System.out.println(Arrays.toString(dcs));
        // 获取单个public修饰的构造方法
        Constructor dc1 = clazz1.getDeclaredConstructor(); //获取空参的构造方法
        System.out.println(dc1);
        Constructor dc2 = clazz1.getDeclaredConstructor(String.class,int.class);
        System.out.println(dc2);
    }
}

class Student{
    private String name;
    private int age;

    public Student() {
    }

    public Student(String name) {
        this.name = name;
    }
    protected Student(int age){
        this.age = age;
    }
    private Student(String name, int age){
        this.name = name;
        this.age = age;
    }
}
/*输出:
[public com.itheima.demo7.Student(java.lang.String), public com.itheima.demo7.Student()]
[private com.itheima.demo7.Student(java.lang.String,int), protected com.itheima.demo7.Student(int), public com.itheima.demo7.Student(java.lang.String), public com.itheima.demo7.Student()]
public com.itheima.demo7.Student()
private com.itheima.demo7.Student(java.lang.String,int)
*/

四. 利用反射获取成员变量

获取成员变量

public class Test {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, NoSuchFieldException {
        // 获取class字节码文件的对象
        Class clazz1 = Class.forName("com.itheima.demo7.Student");
        // 获取public修饰的成员变量
        Field[] fs = clazz1.getFields();
        System.out.println(Arrays.toString(fs));
        // 获取所有的成员变量
        Field[] dfs = clazz1.getDeclaredFields();
        System.out.println(Arrays.toString(dfs));
        // 获取单个public修饰的成员变量
        Field gender = clazz1.getField("gender");
        System.out.println(gender);
        // 获取单个成员变量
        Field name = clazz1.getDeclaredField("name");
        System.out.println(name);
    }
}

class Student{
    private String name;
    private int age;
    public String gender;

    public Student() {
    }

    public Student(String name, int age, String gender) {
        this.name = name;
        this.age = age;
        this.gender = gender;
    }
}
/*输出:
[public java.lang.String com.itheima.demo7.Student.gender]
[private java.lang.String com.itheima.demo7.Student.name, private int com.itheima.demo7.Student.age, public java.lang.String com.itheima.demo7.Student.gender]
public java.lang.String com.itheima.demo7.Student.gender
private java.lang.String com.itheima.demo7.Student.name
*/

五. 利用反射获取成员方法

获取成员方法
和上面的代码类似,就不写代码了,太累了。

六. 反射的作用

反射的作用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值