刚刚掉进java.util.Properties的坑里了……其实也好久没记博客了。java.util.Properties这个类继承至java.util.Hashtable<Object, Object>,常用来表示一些属性。

问题发生在配置某个三方库上,其中有一处参数传入的正是若干属性包装成的Properties。鉴于它继承了Hashtable中的所有方法,我想当然地用了java.util.Hashtable#put(java.lang.Object, java.lang.Object)方法往里面放属性(碰巧属性值既有String类型,又有int、boolean类型,这个方法太和我意了~),而后项目启动时就抛出了空指针。

StackTrace显示出问题的地方是这个三方库从Properties中取出配置参数的几行代码,但是DEBUG看,Properties中各个属性都准确无误,进一步单步,发现了“神奇”的问题——一个明明存在的属性在java.util.Properties#getProperty(java.lang.String)时居然是null?!

问题就出在这个getProperty方法上,下面是它的源码

1
2
3
4
5
public String getProperty(String key) {
Object oval = super.get(key);
String sval = (oval instanceof String) ? (String)oval : null;
return ((sval == null) && (defaults != null)) ? defaults.getProperty(key) : sval;
}

可以看到第3行这里,如果取出的属性值不是String类型,那么就将它置为null。虽然我不太理解为什么这样设计,但至少是吸取了一个教训,往Properties里放属性应当使用java.util.Properties#setProperty(java.lang.String, java.lang.String)方法,虽然它直接调用的还是父类的put方法,也就是让我掉坑里的那家伙,但人家通过形参限制了key、value都只能是String。