背景:项目中用的全局变量,一般通过形如 pubic static final String ABC="abc";然后在项目中用类.属性名的方式调用。
如果变量的值并不固定。比如不同客户定义的值不同,就不能用final修饰。只能用public static String ABC;方式来声明,也可加默认初始值;
这个时候我们就需要一个初始化方法(init())来对变量进行初始化赋值,让其变得有意义。
因为值需要从配置文件中读取,传统方法,可能是根据属性的set方法一个一个设置。假如有10个属性,可能有10段90%相似度的设置代码。 类似 r.setABC(value);
利用reflect(反射),可以自动完成这些工作,前提是:保证.properties文件中的key跟属性名保持一致(这样才能顺利读取到对应的值)
定义类:
public class R{
public static String TOKEN="default-value";
public static String APPID;
...
}
定义R.properties配置文件:
TOKEN=SDLKFJL
APPID=DFSLF
...
定义其中一个init()方法:
/**
* 初始化变量,通过读取properties文件
*/
public static void init(){
System. out.println( "开始初始化");
try {
//1读取配置文件
Class c=R. class;
// InputStream in = Class.forName("com.wupl.constant.R").getResourceAsStream("src/R.properties");
InputStream in = new BufferedInputStream( new FileInputStream("src/R.properties" ));
Properties properties = new Properties();
properties.load(in);
//通过反射获取所有string类型成员变量信息,并以此读取配置文件中的值并赋值。
Field [] fields = c.getDeclaredFields();
for( int i=0;i<fields. length;i++){
Field field = fields[i];
String fieldName=field.getName();
//判断是否是字符串类型,配置文件中有对应的key=value键值
if(field.getGenericType().toString().equals( "class java.lang.String")&&
properties.containsKey( fieldName)){
String value=properties.getProperty(fieldName); //取值
System. out.println( "取到" +fieldName+ "--的值--" +value);
field.set( fieldName, value);
}
}
System. out.println( "初始化完毕" );
} catch (Exception e) {
System. out.println( "初始化失败" );
e.printStackTrace();
}
}
方法原理很简单:利用反射获取R类里面所有的属性,得到 Field数组,遍历,因为配置文件中都是String类型值,所以判断:
如果属性是String 类型(通过field.getGenericType().toString().equals( "class java.lang.String") ),再判断配置文件中是否有对应的key=value值。
条件成立==》则取值,并赋值。
这样R类里面的所以String 类型的成员变量都会取到配置文件中对应的值(如果存在的话)。
而且如果以后增加属性,只需要保持配置文件中key值跟属性名相同,初始化不用修改一句代码。方便扩展。