了解静态代码块,可以先抽几分钟时间看看链接
http://blog.youkuaiyun.com/androidbluetooth/article/details/6454135
先给个示例程序
package it.mark;
import java.util.HashMap;
public class StaticDemo {
public static HashMap<Integer, String> map;
public StaticDemo() {
System.out.println("construct StaticDemo-----");
map = new HashMap<Integer, String>();
map.put(1, "google");
map.put(2, "baidu");
map.put(3, "sina");
// --------省略添加的 4~1113 项数据-----------
map.put(1114, "souhu");
map.put(1115, "git");
map.put(1116, "svn");
}
}
map 是 StaticDemo 类的静态成员
在 StaticDemo 的构造方法里面对 map 进行了实例化。
其他类可以直接访问这个 StaticDemo 类的 map,或者创建 StaticDemo 对象再访问 map
// 直接访问
HashMap<Integer, String> map1 = StaticDemo.map;
String value1 = map1.get(1);
// 通过实例化类来访问
HashMap<Integer, String> map2 = new StaticDemo().map;
String value2 = map2.get(2);
仔细看看这段代码有甚麽问题。
从表面上看,没有任何问题。但是看看 StaticDemo 构造方法,你就会发现
String value1 = map1.get(1);
执行的时候,会报空指针异常的错误。
这是因为,map 对象根本没有被实例化。
那么,我们这样试一试
// 通过实例化类来访问
HashMap<Integer, String> map2 = new StaticDemo().map;
String value2 = map2.get(2);
// 直接访问
HashMap<Integer, String> map1 = StaticDemo.map;
String value1 = map1.get(1);
运行是没有错误的。
原因很简单,在
// 通过实例化类来访问
HashMap<Integer, String> map2 = new StaticDemo().map;
String value2 = map2.get(2);
调用了 StaticDemo 构造方法,从而示例化了 map,那么
// 直接访问
HashMap<Integer, String> map1 = StaticDemo.map;
String value1 = map1.get(1);
由于 map 是 static 的成员变量,已经被实例化,自然可以访问到!
上面的一个例子,其实是我工作当中遇到一个 bug 的缩影。
回过头来,我们可以想一想,在 StaticDemo 构造方法里面做了下面几件事情
1. 实例化 map
2. 为 map 对象添加数据(1000多条)
也就是说,我们每次 new StaticDemo 对象的时候,都要重复上面的事情。
但是,既然 map 是 static 的,为什么不可以使用静态代码块?
package it.mark;
import java.util.HashMap;
public class StaticDemo {
public static HashMap<Integer, String> map;
static {
map = new HashMap<Integer, String>();
map.put(1, "google");
map.put(2, "baidu");
map.put(3, "sina");
// --------省略添加的 4~1113 项数据-----------
map.put(1114, "souhu");
map.put(1115, "git");
map.put(1116, "svn");
}
}
这样做的话,我们可以在其它地方随心所欲的直接访问 map 对象。不用担心 null pointer !
另一个关于 static 的 bug
http://blog.youkuaiyun.com/androidbluetooth/article/details/6823430