类加载器加载配置文件
//创建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);
}