day16——反射

本文详细介绍了如何在Java中加载src目录下的config.properties配置文件,并使用类加载器。同时,深入探讨了反射的概念,展示了如何获取及使用类的构造方法、成员变量和成员方法。此外,还给出了一个实例,演示了如何根据配置文件内容动态调用相应类和方法。
摘要由CSDN通过智能技术生成

加载配置文件

在src目录下创建一个config.properties配置文件,使用类加载器加载配置文件。

//创建集合
Properties properties=new Properties();

//获取src目录下,配置文件的流
InputStream in = ClassLoader.getSystemClassLoader()
    .getResourceAsStream("config.properties");

//加载配置文件到集合
properties.load(in);

反射

反射指的是在运行时,动态的获取任意一个类的任意属性和方法。其中属性用Field表示,方法用Method表示,构造方法用Constructor表示。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tfHpCa8K-1612711002392)(assets/image-20201204104431621.png)]

获取字节码

//1. Class.forName("类的全限定名")
Class clazz1 = Class.forName("com.itheima.Student");

//2. 类名.class
Class clazz2 = Student.class
    
//3. 对象名.getClass()
Class clazz3 = stu.getClass();

反射获取构造方法

//获取字节码对象
Class<?> clazz = Class.forName("com.itheima.demo.Student");

//获取构造方法
Constructor<?> con1 = clazz.getConstructor();
//使用空参数构造方法创建对象
Object stu1 = con1.newInstance();   //等价于 new Student();
System.out.println(stu1);

//获取有一个参数的构造方法
Constructor<?> con2 = clazz.getDeclaredConstructor(String.class);
con2.setAccessible(true); //取消权限检查(暴力反射)
Object stu2 = con2.newInstance("张三"); //等价于  new Student("张三");
System.out.println(stu2);

//获取有两个参数的构造方法
Constructor<?> con3 = clazz.getConstructor(String.class, int.class);
Object stu3 = con3.newInstance("李四", 25); //等价于  new Student("李四",25);
System.out.println(stu3);  

反射获取成员变量并使用

 Field	getField(String name) 
      通过属性名获取一个成员变量
 Field[] getFields() 
      获取所有public修饰的成员变量
 Field	getDeclaredField(String name) 
      通过属性名获取一个私有的成员变量
 Field[] getDeclaredFields() 
      获取所有的成员变量(既包括私有,也包括公有)
Class<?> clazz = Class.forName("com.itheima.demo2.Student");

//创建Student对象
Object stu = clazz.getConstructor().newInstance();

//获取name变量
Field field1 = clazz.getDeclaredField("name");
//暴力反射
field1.setAccessible(true);
//给变量设置值
field1.set(stu,"张三");  //等价于  stu.setName("张三");
System.out.println(stu);

//获取变量的值
Object value = field1.get(stu);  //等价于 stu.getName();
System.out.println(value);


System.out.println("----------------");
Field field2 = clazz.getField("sex");
field2.set(stu,"男");
System.out.println(stu);

Object value2 = field2.get(stu);
System.out.println(value2);

获取成员方法并使用

public Method getMethod(String name, Class<?>... parameterTypes) 
     获取一个公有的成员方法
public Method[]	getMethods() 
    获取所有公有的成员方法(包括父类的方法)
public Method	getDeclaredMethod(String name, Class<?>... parameterTypes) 
    获取一个私有成员方法
 Method[] getDeclaredMethods() 
    获取所有的成员方法(既包括私有,也包括公有)
Class<?> clazz = Class.forName("com.itheima.demo3.Student");

//创建对象
Object stu = clazz.getConstructor().newInstance();

//获取一个成员方法   public void show()
Method m1 = clazz.getMethod("show");
m1.invoke(stu); //执行方法  对象.show();

//获取一个成员方法, private void show(String name)
Method m2 = clazz.getDeclaredMethod("show", String.class);
m2.setAccessible(true);
m2.invoke(stu,"张胜男");

//获取一个成员方法, void show(String name,int age)
Method m3 = clazz.getDeclaredMethod("show", String.class, int.class);
m3.invoke(stu,"李四",20);

//获取一个成员方法,protected int  sum(int a,int b)
Method m4 = clazz.getDeclaredMethod("sum", int.class, int.class);
Object obj = m4.invoke(stu, 4, 8);
System.out.println(obj);

配置文件+反射

  • 写一个配置文件config.properties
#类名
classname=com.itheima.demo4.Teacher
#方法名
methodname=teach
  • 读取配置文件,通过反射获取相应的类和方法
public class Demo4 {
    public static void main(String[] args) throws IOException, ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        //读取配置文件
        Properties properties=new Properties();
        
        //获取配置文件的字节流
        InputStream inputStream =
                ClassLoader.getSystemClassLoader()
            .getResourceAsStream("config.properties");
        properties.load(inputStream);

        //获取类名
        String classname = properties.getProperty("classname");
        //获取方法名
        String methodname = properties.getProperty("methodname");
        //获取类对应的字节码
        Class<?> clazz = Class.forName(classname);
        //创建对象
        Object obj = clazz.getConstructor().newInstance();
        //获取方法
        Method m = clazz.getDeclaredMethod(methodname);
        //让方法执行
        m.invoke(obj);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值