反射、注解、枚举——反射

类加载器加载配置文件

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

//自动加载src目录下的文件,转换为一个字节输入流
InputStream in = Demo1.class.getClassLoader().getResourceAsStream("config.properties");
//读取配置文件
pro.load(in); 

System.out.println(pro);

反射

通过反射可以获取任意类的它的各个组成部分(成员变量、成员方法、以及构造方法),然后在需要的时候执行他们。

在这里插入图片描述

获取字节码

//1. 类名.class
Class clazz1 = Student.class;

//2. 对象名.getClass()
Student stu=new Student();
Class clazz2 = stu.getClass(); 

//3. Class.forName("类的全限定名");
Class clazz3 = Class.forName("com.itheima.demo2.Student");

反射获取构造方法

public Constructor<T> getConstructor(Class<?>... parameterTypes) 
    获取一个public修饰的构造方法
public Constructor<?>[] getConstructors()
    获取所有的public修饰的构造方法

public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes)
    获取一个包括私有的构造方法
public Constructor<?>[] getDeclaredConstructors() 
    获取所有的包括私有的构造方法

以下代码演示,获取构造方法并创建对象

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

    public Student() {
    }

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

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

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", sex='" + sex + '\'' +
                '}';
    }
}
public class Demo3 {
    public static void main(String[] args) throws Exception {
        //获取Student类的字节码
        Class<?> clazz = Class.forName("com.itheima.demo2.Student");

        //获取多个构造方法
        //Constructor<?>[] cons = clazz.getConstructors();
        //Constructor<?>[] cons = clazz.getDeclaredConstructors();
        //for (Constructor<?> con : cons) {
        //    System.out.println(con);
        //}

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

        //获取有两个参数的构造方法,参数分别是String类型和int类型
        Constructor<?> con2 = clazz.getConstructor(String.class, int.class);
        //等价于 Student s2=new Student("张三",20);
        Object obj2 = con2.newInstance("张三", 20);
        System.out.println(obj2);

        //获取有三个参数的构造方法,参数类型分别是Stirng,int,String
        Constructor<?> con3 = clazz.getDeclaredConstructor(
            String.class, int.class, String.class);
        
        //等价于 Student s3=new Student("李四", 30, "男");
        Object obj3 = con3.newInstance("李四", 30, "男"); 
        System.out.println(obj3);
    }
}

反射获取成员变量

public Field getField(String name) 
 	获取一个public修饰的成员变量
public Field[] getFields()  
    获取所有的public修饰的成员变量

public Field getDeclaredField(String name)
    获取一个包括私有的成员变量
public Field[] getDeclaredFields()  
    获取所有的包括私有的成员变量
public class Demo4 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchFieldException {
        //获取Student类的字节码
        Class<?> clazz = Class.forName("com.itheima.demo2.Student");

        //获取所有的成员变量(public)
        //Field[] fields = clazz.getFields();
        //获取所有的成员变量(公有私有都可以)
        //Field[] fields = clazz.getDeclaredFields();
        //for (Field field : fields) {
        //    System.out.println(field);
        //}

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

        //获取一个名称为name的成员变量(public)
        Field f1 = clazz.getField("name"); 
        //设置name属性值
        f1.set(obj, "张三"); //等价于 s.setName("张三");
        //获取name属性值
        Object name_value = f1.get(obj);
        System.out.println(name_value); 

        //获取一个名称为age的成员变量(private)
        Field f2 = clazz.getDeclaredField("age");
        //暴力反射
        f2.setAccessible(true);
        //设置age的值
        f2.set(obj, 18);
        //获取age的值
        Object age_value = f2.get(obj);
        System.out.println(age_value);

        //获取一个名称为sex的成员变量(private)
        Field f3 = clazz.getDeclaredField("sex");
        //暴力反射
        f3.setAccessible(true);
        //设置sex的值
        f3.set(obj,"女");
        //获取sex的值
        Object sex_value = f3.get(obj);
        System.out.println(sex_value);
        
        //打印对象
        System.out.println(obj);
    }
}

反射获取成员方法

public Method getMethod(String name, Class<?>... parameterTypes)
    获取一个public修饰的成员方法,包括父类的方法。
public Method[] getMethods()  
    获取多个public修饰的成员方法

public Method getDeclaredMethod(String name, Class<?>... parameterTypes)
    获取一个包括私有的成员方法
public Method[] getDeclaredMethods() 
    获取所有的成员方法,不包括父类方法。
public class Demo5 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        //获取字节码
        Class<?> clazz = Class.forName("com.itheima.demo2.Student");

        //获取所有的成员方法(public)
//        Method[] ms1 = clazz.getMethods();
//        Method[] ms1 = clazz.getDeclaredMethods();
//        for (Method method : ms1) {
//            System.out.println(method);
//        }

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

        //获取public修饰的show()
        Method m1 = clazz.getMethod("show");
        m1.invoke(obj); //执行


        //获取public修饰的show(String s)
        Method m2 = clazz.getDeclaredMethod("show",String.class);
        //暴力反射
        m2.setAccessible(true);
        m2.invoke(obj,"hahaah");  //obj.show("hahaah");

        //获取public修饰的show(String s,int n)
        Method m3 = clazz.getMethod("show",String.class,int.class);
        m3.invoke(obj,"heiheihei",100);

        //获取toString方法
        Method m4 = clazz.getMethod("toString");
        Object invoke = m4.invoke(obj);
        System.out.println(invoke);
    }
}

反射+配置文件

先写一个配置文件config.properties

classname=com.itheima.demo3.Teacher
methodname=teach

使用Properties集合读取配置文件,再通过反射类的字节码和方法,并让方法执行

//读取配置文件
Properties pro = new Properties();
//通过类加载器加载src目录下的文件,转换为一个InputStream
InputStream in = Demo3.class.getClassLoader().getResourceAsStream("config.properties");
pro.load(in);

//获取类名
String classname = pro.getProperty("classname"); //com.itheima.demo3.Student
//通过类名获取字节码
Class<?> clazz = Class.forName(classname);
//创建对象
Constructor<?> con = clazz.getConstructor(String.class, int.class);
Object obj = con.newInstance("张三", 20);

//获取方法名
String methodname = pro.getProperty("methodname"); //study
//获取方法
Method m = clazz.getDeclaredMethod(methodname);

//执行方法
m.invoke(obj);

BeanUtils工具类

写一个工具类,可以用来给任意对象的任意属性赋值。

/**
     * @param obj 要赋值的JavaBean对象
     * @param map JavaBean对象的属性名和属性值
     */
public static void populate(Object obj, Map<String, Object> map) throws NoSuchFieldException, IllegalAccessException {
    //获取字节码
    Class<?> clazz = obj.getClass();
    //获取所有的成员变量
    Set<String> keys = map.keySet();
    for (String key : keys) {
        //获取成员变量
        Field field = clazz.getDeclaredField(key);
        field.setAccessible(true); //暴力反射

        //获取成员变量的值
        Object value = map.get(key);
        field.set(obj, value);
    }
}

成员变量

Set<String> keys = map.keySet();
for (String key : keys) {
    //获取成员变量
    Field field = clazz.getDeclaredField(key);
    field.setAccessible(true); //暴力反射

    //获取成员变量的值
    Object value = map.get(key);
    field.set(obj, value);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值