需求
对象的相关信息存储在javabean.properties文件中,通过读取properties文件中的信息,实例化对象,要求程序不能硬编码,即程序可以通用,针对不同的对象,都可以实例化。仅需修改配置文件,不需要更改代码。
实现代码
import java.io.FileReader;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.util.Properties;
/**
* 实例化对象
*/
public class AddInstance {
public static void main(String[] args) throws Exception {
// 读取本地javabean.properties
Properties properties = new Properties();
properties.load(new FileReader("C:\\Users\\1\\IdeaProjects\\javaSE\\javabean.properties"));
// 根据javabean.properties中的className值获取对应的字节码对象
Class className = Class.forName((String) properties.get("className"));
// 获取构造器
Constructor constructor = className.getConstructor();
// 获取实例化对象
Object obj = constructor.newInstance();
// 获取所有的变量对象
Field[] fields = className.getDeclaredFields();
// 遍历变量对象
for (Field field : fields) {
// 分割变量对象,需要注意”.“需要转义
String[] split = (field.toString()).split("\\.");
// 获取属性名
String attribute = split[split.length - 1];
// 将属性的访问设置为true
field.setAccessible(true);
// 定义Object对象
Object o;
// 如果该对象的某个属性是int类型
if (field.getType() == int.class) {
// 将从javabean.properties中获取到的对应的该值转为Integer类型
o = Integer.parseInt((String) properties.get(attribute));
} else {
// 不是int类型,直接将取出javabean.properties中的值
o = properties.get(attribute);
}
// 写入
field.set(obj, o);
}
System.out.println("通过配置文件创建了对象,并赋值结果是:" + obj);
}
}
需要注意以下两点:
(1)获取javaBean的属性对象后,用“.”(点)进行分割时,需要转义,即“\\.”,不然分割不出效果
System.out.println("------------------------------------------------------------");
System.out.println(field.toString());
String[] split = (field.toString()).split("\\.");
System.out.println(Arrays.toString(split));
String[] split1 = (field.toString()).split(".");
System.out.println(Arrays.toString(split1));
(2)因为从properties文件中读出来的值都是字符串的,所以在写入对象值时需要判断,即判断对象的该属性(比如)是int类型,则把从properties中读取出来的该属性的值转为int类型
// 如果该对象的某个属性是int类型
if (field.getType() == int.class) {
// 将从properties.properties中获取到的对应的该值转为Integer类型
o = Integer.parseInt((String) properties.get(attribute));
} else {
// 不是int类型,直接将取出properties.properties中的值
o = properties.get(attribute);
}
总结和分析
通过反射和读取本地配置文件的方式来实例化对象,看似避免了“硬编码”,实例化不同对象不需要更改代码。但是,仍有以下几点麻烦之处:
(1)实例化不同的对象,需要更改配置文件的className值,即需要实例化javaBean的全类名;
(2)另外,如果javaBean属性中有非字符串类型的,则需要增加判断;
(3)而且如果多个javaBean的实例化信息存放在properties内,不免会出现属性重复的情况。比如Person类有name属性,User类也有name属性,这时就需要创建多个properties文件,不免有些麻烦。