问题描述:
在项目开发过程中,我们建立许多的工具类,比如说:网络请求、图片加载,判断服务是否启动等。其调用方式最常用的有两种:1.直接使方法静态,这样就可以用类名.方法名直接调用。大家都知道,静态方法在一个项目中出现多次会影响项目的内存消耗,所以有好多人会选择第二种方式。2.方法不静态化,使用单例创建对象后,再调用方法。那么这个Bug就是在使用第2种方式调用方法的时候所造成的。
代码如下:
public class BugUtil {
private static BugUtil instance = null;
public String str=null;
public BugUtil() {
}
/**
* 加上synchronized,但是每次调用实例时都会加载
*/
public static BugUtil getInstance() {
synchronized (BugUtil.class) {
if (instance == null) {
instance = new BugUtil();
}
}
return instance;
}
/**
* 对str进行赋值
*/
public void setStr(){
str="我已经给str赋过值了";
}
}
在MainActivity中调用打印log
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
BugUtil bugUtil=new BugUtil();
bugUtil.setStr();
Log.i("sunmenglong", "onCreate: ..............."+BugUtil.getInstance().str);
}
打印出的log:
10-28 13:46:16.501 6718-6718/? I/sunmenglong: onCreate: ...............null
我当时的疑惑就是,明明在上一行的代码当中,已经给str赋值过了,为什么打印的还是为空?
我们再次看一下这个调用的代码:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
BugUtil bugUtil=new BugUtil();
bugUtil.setStr();
Log.i("sunmenglong", "onCreate: ..............."+BugUtil.getInstance().str);
}
区别就在于:我在赋值的时候是new出来的一个对象,而在打印的时候是调用的单例。所以,赋值的str和取值的str不是同一个实例,造成了这样的误解。
如果我们在使用单例写工具类的时候,一定要使无参构造方法私有化,这样外界在调用的时候就创建不了实例了!
希望这篇博客对于遇到同样问题的码农们有所帮助!