加载配置文件
在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);
}
}