难用到令人抓狂的w3c标准DOM解析API
Jun3
被.Net毒害太深,以至于离开.Net就发现自己原来是个菜鸟,一件在.net中可以很简单完成的事情,到了java下面可能就要让你抓狂。要解析Xml,Android提供的jar中包含了最基本的w3c DOM API和标准的SAX(Simple API for XML),因为常年沉侵在.Net的温床中,导致了对这些标准API的从来不闻不问,当使用到这些API时,也就只有抓狂了。。。没有XPath支持不说,看看下面这个Xml片段在标准DOM API中的Node结构便知道抓狂的含义了:
<root>
<!–xxx–>
<sub>123</sub>
</root>
首先,DOM里的Node不是在.net理解中的<a></a>这个叫一个node,任何xml中的元素都是node,<a></a>只是一种type为ELEMENT_NODE的node,此外还有很多type的node,常用的还有TEXT_NODE,上面XML片段的Node模型如下(*表示缩进):
root (NodeType: ELEMENT_NODE)
****\n (NodeType: TEXT_NODE,抓狂1:<root>后面的换行符\n也是一个Node!一个文本类型的Node,标准API中可以用getNodeValue()得到“\n”)
****<!–xxx–> (NodeType: COMMENT_NODE)
****\n (NodeType: TEXT_NODE,还是\n)
****sub (NodeType: ELEMENT_NODE)
********123 (NodeType: TEXT_NODE,抓狂2:<sub>中的文字也是一个node,getNodeValue()得到”123″。这个文字不是sub节点的nodeValue,而是一个新的node,sub节点的nodeValue会直接返回null)
****\n (NodeType: TEXT_NODE,sub节点后的换行符)
如果之前不了解w3c标准DOM API,很抱歉,上面的知识得花费你个把小时调试你才能学会。幸运的是除了标准API,我们还有更多的选择,DOM4J就是一个不那么让人抓狂的开源XML解析工具包。
此static非彼static
Dec5
(以下内容是对一个简单但容易混淆的基础概念的备注,适用于写Java的C#er。请各位Javaer,达人,牛人,机器人以及太空人自动忽视,否则看后被雷后果自负)
对于C#er来说静态类再熟悉不过了,然而在Java中由static声明的class绝非C#中的static class,2者的意思可以说是差个十万八千里远,以致于我在google上搜索“Java 静态类”的前几条结果竟然都没有将这个概念说清楚,而且还有一摩尔多的帖子将Java中的static class和C#的static class混为一潭。(真不明白那几个大大是怎么学习的啊~~~,其实这个概念在《Core Java》中解释的粉清楚,而且只用了1页多一点,看来和我一样的剑宗派还真不少啊)
C#中的静态类就是只包含静态方法和静态字段不能被实例化的类,这个不用多说。但是Java中根本就没有这种类,要得到类似的效果只能使用单件模式模拟。那Java中的static class是什么意思呢?Java中的static class只能申明在一个类的内部,也就是说只能是一个嵌套类或者叫做内部类,并且这个内部类并不是C#中的那种不能实例化的类,这种类是可以实例化的,那么它表示什么意思呢?例如下面的Java代码:
public class OuterClass {
public int Field1;
private class InnerClass{
public void Foo(){
int myField = Field1;
//……
}
}
public void OuterFoo(){
InnerClass innerObj = new InnerClass();
innerObj.Foo();
}
}
这段代码中的InnerClass不是static的,那么这会发生什么呢?注意到InnerClass中的Foo方法使用到了OuterClass中的Field1!也就是说当我们在OuterClass的OuterFoo方法中构造InnerClass的实例时,OuterClass当前实例的this指针以某种方式被传递到了构造出的InnerClass实例中,这样在InnerClass的Foo方法中才可能访问到OuterClass中的Field1,实际上这是Java编译器干的事情,Java编译器编译的OuterFoo方法实际上是:
public void OuterFoo(){
InnerClass innerObj = new InnerClass(this);
innerObj.Foo();
}
再来说static内部类就清楚了,如果InnerClass是static的,那么在构造InnerClass的实例时(注意,即使是static的内部类也是可以构造实例的,不要和C#混为一谈)编译器就不会干上面那件事情,所以InnerClass中的方法就没有办法使用OuterClass中的字段了。至于为什么这个关键字会是对C#er来说很混淆的static?想想如果上面的OuterFoo方法是一个静态方法,那么编译器就根本没有办法在这个方法内使用this指针,所以静态方法中构造和使用的内部类就必须声明为static的。
搞清楚这个问题,各位C#er无论是在写Java或者看开源的Java代码的时候遇到里面的static,就不会有抓耳挠腮想自杀的感觉了~~~ 最后ps,Java和C#虽然非常类似,但是实际上还是有很多概念相当的混淆,对于要经常看开源Java代码的C#er来说,搞清楚这些概念还是很有必要的。