反射

本文深入解析Java反射机制,介绍如何在运行时动态获取类的属性和方法,展示三种获取字节码文件的方法,并演示如何使用反射创建对象及访问私有成员。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Java的反射机制是在运行状态中,对于任意一个类,都能知道这个类的属性和方法,对于任意一个对象,都能使用该类的成员与方法,这种动态获取的以及动态调用方法的功能称为反射机制。
通过反射技术, 我们可以拿到该字节码文件中所有的东西, 例如成员变量, 成员方法, 构造方法, 而且还包括私有的。

1 字节码文件获取的三种方式
1.1 对象.getClass() 此方法用于在Object对象已经存在的情况下,可使用
1.2 类名.class() 类名.class是一个静态的属性,可直接访问
1.3 Class.forName(全类名) 通过Class类中的静态方法, 指定字符串, 该字符串是类的全类名(包名+类名) ,此方法需要处理异常
例子如下:

package cn.itcast_03;

public class ReflectDemo {
    public static void main(String[] args) throws ClassNotFoundException {
        //对象名.getClass()
        Student s = new Student();
        Class cls = s.getClass();
        System.out.println(cls); //class cn.itcast_03.Student 

        //类名.class 
        Class cls1 = Student.class;
        System.out.println(cls1);//class cn.itcast_03.Student

        //Class.forName(全类名)方法
        //此方法需要处理异常 ClassNotFoundException
        Class cls2 = Class.forName("cn.itcast_03.Student");
        System.out.println(cls2);//class cn.itcast_03.Student

    }

}

2 字节码对象是描述.class文件的
面向对象的构造:
成员变量
构造方法
成员方法
2.1 反射构造方法创造对象
步骤:
1 取得class对象
2 取得class构造
3 创建实例

package cn.itcast_03;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

public class ConstructorDemo {
    public static void main(String[] args) throws ClassNotFoundException,
            NoSuchMethodException, SecurityException, InstantiationException,
            IllegalAccessException, IllegalArgumentException,
            InvocationTargetException {
        //通过类.newInstance()
        Class cls = Class.forName("cn.itcast_03.Student");

        Object obj = cls.newInstance();
        System.out.println(obj); // cn.itcast_03.Student@47abfd68
        //取得构造方法后再创建实例
        Class cls1 = Class.forName("cn.itcast_03.Student");
        Constructor con = cls1.getConstructor();
        Object obj1 = con.newInstance();
        System.out.println(obj1);//cn.itcast_03.Student@2d7fc1e7

    }

}

newInstance() 与getConstructor()的区别:
newInstance()只能创建无参构造
getConstructor()可取得所有构造,根据传入参数取得对应构造参数实例

  1. 获得类成员
    3.1 获取公有成员
    Field f = 类.getField()
    获取私有成员需要使用: 类.getDeclaredFields();
    若需要设置私有成员的值,则需要设置属性.setAccessible(true)
package cn.itcast_03;

import java.lang.reflect.Field;

public class FieldDemo {
    public static void main(String[] args) throws ClassNotFoundException,
            InstantiationException, IllegalAccessException,
            NoSuchFieldException, SecurityException {
        // 获取字节码对象
        Class cls = Class.forName("cn.itcast_03.Student");
        // 创建对象
        Object obj = cls.newInstance();
        //获取所有成员
        Field[] f = cls.getDeclaredFields();// 访问该类的所有公有成员方法
        for (Field field : f) {
            System.out.println(field);
        }

        Field name = cls.getDeclaredField("name");
        System.out.println(name);

        Field age = cls.getDeclaredField("age");
        System.out.println(age);
        //设置可访问
        name.setAccessible(true);
        age.setAccessible(true);

        name.set(obj, "lilizhou");
        age.set(obj, 6);
        System.out.println(obj);

    }

}
  1. 获取成员方法
    公有单个成员方法: cls.getMethod(name, parameterTypes)
    公有所有方法:cls.getMethods()
    私有单个成员方法:getDeclaredMethod(name, parameterTypes)
package cn.itcast_03;

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

public class MethodDemo {
    public static void main(String[] args) throws InstantiationException,
            IllegalAccessException, ClassNotFoundException,
            NoSuchMethodException, SecurityException, IllegalArgumentException,
            InvocationTargetException {
        Class cls = Class.forName("cn.itcast_03.Student");

        Object obj = cls.newInstance();
        Method[] mes = cls.getMethods();
        for (Method m : mes) {
            System.out.println(m);
        }

        //cls.getDeclaredMethod(name, parameterTypes)
        //私有方法
        Method me = cls.getDeclaredMethod("show");
        me.setAccessible(true);//需要设置访问标识才可以访问
        me.invoke(obj);

        Method me1 = cls.getMethod("toString");
        me1.invoke(obj);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值