反射原理展示

这篇博客详细介绍了Java中的反射原理和类加载器的工作机制。通过示例代码展示了如何获取类的字节码对象,以及如何利用反射来创建对象、访问和修改成员变量、调用成员方法。此外,还提供了从配置文件读取数据并利用反射实例化对象的完整流程。
摘要由CSDN通过智能技术生成

反射原理:把字节码对象通过类加载器(类加载器)获取到相应的对象(成员变量,成员方法,局部变量)

类加载器原理:

获取到当前类 Phone的对象one 的字节码对象呢?

class cal = one.getclass();

获取到Phone类字节码对象

class cal = Phone.class;

获取到

当前类的全名字符串

class cal = class.forName("全类名")

package demo;        

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

public class demo1 {
    public static void main(String[] args) throws IOException {
        //获取到类加载器对象
方式一:
        ClassLoader  loader = ClassLoader.getSystemClassLoader();
方式二:
InputStream is = ClassLoader.getSystemResourceAsStream("config.properties");
        //可加载来自于src下面的文件信息,获取到流对象
        //转化成为字节输出流
        InputStream is = loader.getResourceAsStream("config.properties");
        //采用properpties加载数据
        Properties properties  = new Properties();
        properties.load(is);
        is.close();
        //获取到数据
        String name = properties.getProperty("name");
        String pass = properties.getProperty("pass");
        System.out.println("name = " + name);
        System.out.println("pass = " + pass);
    }

}

反射获取构造方法:

1. Constructor[] array1 = clazz.getConstructors();  //获取所有 public 修饰的构造方法
2. Constructor c2 = clazz.getConstructor(String.class, int.class);  //获取指定的某个public修饰的构造方法。
3. Constructor[] array3 = clazz.getDeclaredConstructors();  //获取所有的构造方法,包括私有
4. Constructor c4 = clazz.getDeclaredConstructor(int.class); //获取指定的某个构造方法,包括私有

使用构造方法:

1. Object o = c.newInstance("家海");    //采用构造方法 c 去创建对象 o 根据需求传递参数
2. c.setAccessible(true);  //暴力访问,取消私有 private 权限检查。
3. Object o = clazz.newInstance();  //采用字节码去创建对象,跳过了获取构造方法的过程。调用的是 系统默认无参数构造方法

获取成员变量

1. Field[] array1 = clazz.getFields();  //获取所有 public 修饰的成员变量
2. Field f2 = clazz.getField(String);  //获取指定的某个public修饰的成员变量
3. Field[] array3 = clazz.getDeclaredFields();  //获取所有的成员变量,包括私有
4. Field f4 = clazz.getDeclaredField(String); //获取指定的某个成员变量,包括私有

使用成员变量

 
1. 设置值 genderField.set(stu,"男");   //参数1:对象   参数2:值
2. 获取值 Object value1 = genderField.get(stu);  //参数: 对象, 返回值: 获取到成员变量里面的值
3. 暴力访问 genderField.setAccessible(true);  //暴力访问,取消私有权限检查

获取成员方法

1. Method[] array1 = clazz.getMethods();  //获取所有 public 修饰的成员方法, 包括父类public方法
2. Method m2 = clazz.getMethod(String,Class...);  //获取指定的某个public修饰的成员方法,可变参数是:方法参数的字节码
3. Method[] array3 = clazz.getDeclaredMethods();  //获取所有的成员方法,包括私有,只有自己的方法,没有父类方法
4. Method m4 = clazz.getDeclaredMethod(String, int.class, int.class); //获取指定的某个成员方法,包括私有

使用成员方法:

1. 调用方法   Object 返回值 = 方法对象.invoke(方法所在类的对象, 方法参数1, 方法参数2);
2. 暴力访问   方法对象.setAccessible(true);
username=zhangsan
password=123456
className=blb.chc03.User

package blb.chc03;
 
//定义用户类
public class User {
 
    private String username;
    private String password;
    
    @Override
    public String toString() {
        return "User{" +
                "username='" + username + '\'' +
                ", password='" + password + '\'' +
                '}';
    }
}

public class Test {
    //读取文件的数据,给成员变量自动赋值,展示结果
    public static void main(String[] args) throws Exception{
        //获取到来自于文件当中的数据。
        //config.properties 文件存在于 src 目录下面的
        InputStream is = ClassLoader.getSystemResourceAsStream("config.properties");
        Properties pp = new Properties();
        pp.load(is);
        String username = pp.getProperty("username");
        String password = pp.getProperty("password");
        String className = pp.getProperty("className");
        is.close();
        //采用反射的方式,获取到对象, 创建对象
        Class  clazz = Class.forName(className);
        Constructor c = clazz.getDeclaredConstructor();
        Object o = c.newInstance();
        //给成员变量赋值
        Field usernameFiled = clazz.getDeclaredField("username");
        usernameFiled.setAccessible(true);
        usernameFiled.set(o,username);
        Field passwordField = clazz.getDeclaredField("password");
        passwordField.setAccessible(true);
        passwordField.set(o,password);
        //展示结果
        System.out.println("o = " + o);  //o = User{username='zhangsan', password='123456'}
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值