Properties如何使用(properties,编程语言)

时间:2024-05-02 13:50:43 作者 : 石家庄SEO 分类 : 编程语言
  • TAG :

01. 摘要

Map 的实现类有 HashMap、LinkedHashMap、TreeMap、IdentityHashMap、WeakHashMap、Hashtable、Properties 等等。

Properties如何使用

02. 简介

Properties 类是 java 工具包中非常重要的一个类,比如在实际开发中,有些变量,我们可以直接硬写入到自定义的 java 枚举类中。

但是有些变量,在测试环境、预生产环境、生产环境,变量所需要取的值都不一样,这个时候,我们可以通过使用 properties 文件来加载程序需要的配置信息,以达到一行代码,多处环境都可以运行的效果!

最常见的比如 JDBC 数据源配置文件,properties文件以.properties作为后缀,文件内容以键=值格式书写,左边是变量名称,右边是变量值,用#做注释,比如新建一个jdbc.properties文件,内容如下:

Properties如何使用

Properties 类是 properties 文件和程序的中间桥梁,不论是从 properties 文件读取信息,还是写入信息到 properties 文件,都要经由 Properties 类。

好了,唠叨了这么多,咱们回到本文要介绍的主角Properties!

从集合 Map 架构图可以看出,Properties 继承自 Hashtable,表示一个持久的 map 集合,属性列表以 key-value 的形式存在,Properties 类定义如下:

publicclassPropertiesextendsHashtable<Object,Object>{......}

Properties 除了继承 Hashtable 中所定义的方法,Properties 也定义了以下几个常用方法,如图所示:

Properties如何使用

常用方法介绍

set 方法(添加修改元素)

set 方法是将指定的 key, value 对添加到 map 里,在添加元素的时候,调用了 Hashtable 的 put 方法,与 Hashtable 不同的是, key 和 value 都是字符串。

打开 Properties 的 setProperty 方法,源码如下:

publicsynchronizedObjectsetProperty(Stringkey,Stringvalue){//调用父类Hashtable的put方法returnput(key,value);}

方法测试如下:

publicstaticvoidmain(String[]args){Propertiesproperties=newProperties();properties.setProperty("name1","张三");properties.setProperty("name2","张四");properties.setProperty("name3","张五");System.out.println(properties.toString());}

输出结果:

{name3=张五, name2=张四, name1=张三}

get 方法(搜索指定元素)

get 方法根据指定的 key 值返回对应的 value,第一步是从调用 Hashtable 的 get 方法,如果有返回值,直接返回;如果没有返回值,但是初始化时传入了defaults变量,从 defaults变量中,也就是 Properties 中,去搜索是否有对于的变量,如果有就返回元素值。

打开 Properties 的 getProperty 方法,源码如下:

publicStringgetProperty(Stringkey){//调用父类Hashtable的get方法Objectoval=super.get(key);Stringsval=(ovalinstanceofString)?(String)oval:null;//进行变量非空判断return((sval==null)&&(defaults!=null))?defaults.getProperty(key):sval;}

查看 defaults 这个变量,源码如下:

publicclassPropertiesextendsHashtable<Object,Object>{protectedPropertiesdefaults;}

这个变量在什么时候赋值呢,打开源码如下:

publicProperties(Propertiesdefaults){this.defaults=defaults;}

可以发现,在 Properties 构造方法初始化阶段,如果你给了一个自定义的 defaults ,当调用 Hashtable 的 get 方法没有搜索到元素值的时候,并且 defaults 也不等于空,那么就会进一步在 defaults 里面进行搜索元素值。

方法测试如下:

publicstaticvoidmain(String[]args){Propertiesproperties=newProperties();properties.setProperty("name1","张三");properties.setProperty("name2","张四");properties.setProperty("name3","张五");//将properties作为参数初始化到newProperties中PropertiesnewProperties=newProperties(properties);newProperties.setProperty("name4","李三");//查询key中name1的值System.out.println("查询结果:"+properties.getProperty("name1"));}

输出结果:

通过key查询结果:张三

load方法(加载配置文件)

load 方法,表示将 properties 文件以输入流的形式加载文件,并且提取里面的键、值对,将键值对元素添加到 map 中去。

打开 Properties 的 load 方法,源码如下:

publicsynchronizedvoidload(InputStreaminStream)throwsIOException{//读取文件流load0(newLineReader(inStream));}

load0 方法,源码如下:

privatevoidload0(LineReaderlr)throwsIOException{char[]convtBuf=newchar[1024];intlimit;intkeyLen;intvalueStart;charc;booleanhasSep;booleanprecedingBackslash;//一行一行的读取while((limit=lr.readLine())>=0){c=0;keyLen=0;valueStart=limit;hasSep=false;precedingBackslash=false;//判断key的长度while(keyLen<limit){c=lr.lineBuf[keyLen];if((c=='='||c==':')&&!precedingBackslash){valueStart=keyLen+1;hasSep=true;break;}elseif((c==''||c=='\t'||c=='\f')&&!precedingBackslash){valueStart=keyLen+1;break;}if(c=='\\'){precedingBackslash=!precedingBackslash;}else{precedingBackslash=false;}keyLen++;}//获取值的起始位置while(valueStart<limit){c=lr.lineBuf[valueStart];if(c!=''&&c!='\t'&&c!='\f'){if(!hasSep&&(c=='='||c==':')){hasSep=true;}else{break;}}valueStart++;}//获取文件中的键和值参数Stringkey=loadConvert(lr.lineBuf,0,keyLen,convtBuf);Stringvalue=loadConvert(lr.lineBuf,valueStart,limit-valueStart,convtBuf);//调用Hashtable的put方法,将键值加入map中put(key,value);}}

好了,我们来在src/recources目录下,新建一个custom.properties配置文件,内容如下:

#定义一个变量名称和值userName=李三userPwd=123456userAge=18userGender=男userEmail=123@123.com

方法测试如下:

publicclassTestProperties{publicstaticvoidmain(String[]args)throwsException{//初始化PropertiesPropertiesprop=newProperties();//加载配置文件InputStreamin=TestProperties.class.getClassLoader().getResourceAsStream("custom.properties");//读取配置文件,指定编码格式,避免读取中文乱码prop.load(newInputStreamReader(in,"UTF-8"));//将内容输出到控制台prop.list(System.out);}}

输出结果:

userPwd=123456

userEmail=123@123.com

userAge=18

userName=李三

userGender=男

propertyNames方法(读取全部信息)

propertyNames 方法,表示读取 Properties 的全部信息,本质是创建一个新的 Hashtable 对象,然后将原 Hashtable 中的数据复制到新的 Hashtable 中,并将 map 中的 key 全部返回。

打开 Properties 的 propertyNames 方法,源码如下:

publicEnumeration<?>propertyNames(){Hashtable<String,Object>h=newHashtable<>();//将原map添加到新的Hashtable中enumerate(h);//返回Hashtable中全部的key元素returnh.keys();}

enumerate 方法,源码如下:

privatesynchronizedvoidenumerate(Hashtable<String,Object>h){//判断Properties中是否有初始化的配置文件if(defaults!=null){defaults.enumerate(h);}//将原Hashtable中的数据添加到新的Hashtable中for(Enumeration<?>e=keys();e.hasMoreElements();){Stringkey=(String)e.nextElement();h.put(key,get(key));}}

方法测试如下:

publicstaticvoidmain(String[]args)throwsException{//初始化PropertiesPropertiesprop=newProperties();//加载配置文件InputStreamin=TestProperties.class.getClassLoader().getResourceAsStream("custom.properties");//读取配置文件,指定读取编码UTF-8,防止内容乱码prop.load(newInputStreamReader(in,"UTF-8"));//获取Properties中全部的key元素EnumerationenProp=prop.propertyNames();while(enProp.hasMoreElements()){Stringkey=(String)enProp.nextElement();Stringvalue=prop.getProperty(key);System.out.println(key+"="+value);}}

输出内容如下:

userPwd=123456

userEmail=123@123.com

userAge=18

userName=李三

userGender=男

总结

Properties 继承自 Hashtable,大部分方法都复用于 Hashtable,比如,get、put、remove、clear 方法,**与 Hashtable 不同的是, Properties中的 key 和 value 都是字符串,**如果需要获取 properties 中全部内容,可以先通过迭代器或者 propertyNames 方法获取 map 中所有的 key 元素,然后遍历获取 key 和 value。

需要注意的是,Properties 中的 setProperty 、load 方法,都加了synchronized同步锁,用来控制线程同步。

03. properties 文件的加载方式

在实际开发中,经常会遇到读取配置文件路径找不到,或者读取文件内容乱码的问题,下面简单介绍一下,properties 文件的几种常用的加载方式。

properties 加载文件的方式,大致可以分两类,第一类是使用 java.util.Properties 的 load 方法来加载文件流;第二类是使用 java.util.ResourceBundle 类来获取文件内容。

在src/recources目录下,新建一个custom.properties配置文件,文件编码格式为UTF-8,内容还是以刚刚那个测试为例,各个加载方式如下!

通过文件路径来加载文件

这类方法加载文件,主要是调用 Properties 的 load 方法,获取文件路径,读取文件以流的形式加载文件。

方法如下:

Propertiesprop=newProperties();//获取文件绝对路径StringfilePath="/coding/java/src/resources/custom.properties";//加载配置文件InputStreamin=newFileInputStream(newFile(filePath));//读取配置文件prop.load(newInputStreamReader(in,"UTF-8"));System.out.println("userName:"+prop.getProperty("userName"));

输出结果:

userName:李三

通过当前类加载器的getResourceAsStream方法获取

这类方法加载文件,也是调用 Properties 的 load 方法,不同的是,通过类加载器来获取文件路径,如果当前文件是在src/resources目录下,那么直接传入文件名就可以了。

方法如下:

Propertiesprop=newProperties();//加载配置文件InputStreamin=TestProperties.class.getClassLoader().getResourceAsStream("custom.properties");//读取配置文件prop.load(newInputStreamReader(in,"UTF-8"));System.out.println("userName:"+prop.getProperty("userName"));

输出结果:

userName:李三

使用ClassLoader类的getSystemResourceAsStream方法获取

和上面类似,也是通过类加载器来获取文件流,方法如下:

Properties prop = new Properties();//加载配置文件InputStream in = ClassLoader.getSystemResourceAsStream("custom.properties");//读取配置文件prop.load(new InputStreamReader(in, "UTF-8"));System.out.println("userName:"+prop.getProperty("userName"));

输出结果:

userName:李三

使用 ResourceBundle 类加载文件

ResourceBundle 类加载文件,与 Properties 有所不同,ResourceBundle 获取 properties 文件不需要加.properties后缀名,只需要文件名即可。

ResourceBundle 是按照iso8859编码格式来读取原属性文件,如果是读取中文内容,需要进行转码处理。

方法如下:

//加载custom配置文件,不需要加`.properties`后缀名ResourceBundleresource=ResourceBundle.getBundle("custom");//转码处理,解决读取中文内容乱码问题Stringvalue=newString(resource.getString("userName").getBytes("ISO-8859-1"),"UTF-8");System.out.println("userName:"+value);

输出结果:

userName:李三

 </div> <div class="zixun-tj-product adv-bottom"></div> </div> </div> <div class="prve-next-news">
本文:Properties如何使用的详细内容,希望对您有所帮助,信息来源于网络。
上一篇:Jython 2.2的新增特性有哪些下一篇:

11 人围观 / 0 条评论 ↓快速评论↓

(必须)

(必须,保密)

阿狸1 阿狸2 阿狸3 阿狸4 阿狸5 阿狸6 阿狸7 阿狸8 阿狸9 阿狸10 阿狸11 阿狸12 阿狸13 阿狸14 阿狸15 阿狸16 阿狸17 阿狸18