SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。

源起:

今天阅读源码时发现一个地方不理解:

为什么以下代码第10行 get() 之后value为null时还去 getProperty() 呢?

org.springframework.util.CollectionUtils

 1   public static <K, V> void mergePropertiesIntoMap(Properties props, Map<K, V> map) {
 2         if (map == null) {
 3             throw new IllegalArgumentException("Map must not be null");
 4         } else {
 5             String key;
 6             Object value;
 7             if (props != null) {
 8                 for(Enumeration en = props.propertyNames(); en.hasMoreElements(); map.put(key, value)) {
 9                     key = (String)en.nextElement();
10                     value = props.get(key);
11                     if (value == null) {
12                         value = props.getProperty(key);
13                     }
14                 }
15             }
16 
17         }
18     }

 

跟进去发现Properties类除了继承HashTable用于存储<K, V>数据之外,自身还持有一个

protected Properties defaults;

因此就相当于可以无限嵌套了吧。。。

 

测试:

Properties有些需要避坑的地方稍微整理了下:

 1     @Test
 2     public void javaCoreProperties () {
 3         // public class Properties extends Hashtable<Object,Object>
 4 
 5         // 初始化时传入的作为default属性(Properties类型)存储
 6         Properties props = new Properties(System.getProperties());
 7         // 调用内部put方法,与put仅形参类型不同
 8         props.setProperty("base.date", "2019-05-09");
 9         // 相比于setProperty适用范围更广,它的形参都是Object类型
10         props.put("base.time", "14:15:00");
11         props.put("base.object", new Date());
12 
13         System.out.println(props.get("base.date"));
14         System.out.println(props.getProperty("base.date"));
15 
16         System.out.println(props.get("base.time"));
17         System.out.println(props.getProperty("base.time"));
18 
19         // get与getProperty不等价
20         // get仅获取put进去的存储在父类HashTable中的数据
21         System.out.println(props.get("java.runtime.version"));
22         // getProperty会优先在查找父类HashTable中的数据,如果没有再到自己拥有的default中查找;查找方法依然是跟这里相同
23         System.out.println(props.getProperty("java.runtime.version"));
24 
25         // 可以获取对象
26         System.out.println(props.get("base.object"));
27         // 获取到Value对象,判断发现不是String类型,再去default中找,依然找不到,返回null
28         System.out.println(props.getProperty("base.object"));
29 
30 
31         // Key和Value不能为空,否则抛出NPE,这是HashTable决定的,HashMap就没有这个限制
32         //props.put(new Object(), null); // 有校验
33         //props.put(null, 123); //计算Key的hashCode时引发
34 
35         // 这个会引起java.lang.ClassCastException,因为list遍历时,会将Key和Value强制转化为String
36         //props.put(new Object(), 123);
37         props.put("007", "123");
38         props.remove("base.object");
39 
40         props.list(System.out);
41     }

 

运行输出:

2019-05-09
2019-05-09
14:15:00
14:15:00
null
1.8.0_144-b01
Thu May 09 15:09:02 CST 2019
null
-- listing properties --
base.time=14:15:00
java.runtime.name=Java(TM) SE Runtime Environment
sun.boot.library.path=C:\DevBaseFiles\Java\jdk1.8.0_144\jre...
java.vm.version=25.144-b01
base.date=2019-05-09
java.vm.vendor=Oracle Corporation
...

 

欢迎提出意见或建议,共同进步。

 

扫码关注我们
微信号:SRE实战
拒绝背锅 运筹帷幄