`

【单例】单例在全局变量中引用变成了多例

    博客分类:
  • Java
阅读更多

单例在编程中经常使用,但在全局变量中应用会出现一些问题。

 

例子:

public class Tst {
	public static void main(String[] args) {
		A.getInstance();
	}
}

class Glbl {
	static {
		System.out.println("In class GlblVars");
	}
	public static String log = "I love java.";
	public static A a = A.getInstance();
}

class A {
	static int instanceNum = 0;
	
	private A() {
		instanceNum ++;
		int n = instanceNum;
		System.out.println(n +" create instance A");
		System.out.println(Glbl.log);
		System.out.println(n +" create instance A done");
	}
	
	private static A instance;
	public static A getInstance() {
		if (instance == null) {
			System.out.println("In class A");
			instance = new A();
		}
		return instance;
	}
}

 

运行结果 写道
In class A
1 create instance A
In class GlblVars
In class A
2 create instance A
I love java.
2 create instance A done
I love java.
1 create instance A done

 

类A生成了,两个对象,因为在调用【A.getInstance();】的时候,给A初始化,A的构造函数中又使用了全局变量【Glbl.log】,这样java虚拟机就会载入类Glbl,这样就会把里面的static的变量a初始化,就又生成了一个A对象了。

 

关键点就是A的构造函数又引用了有A静态变量的类。

 

消除这个问题:

1,去除Glbl 中的静态变量A。【推荐这种因为A.getInstance();这种访问本来就是全局的了,没必要在画蛇添足。】

2,使用Glbl.a来访问A的实例,而不是【A.getInstance();】。

 

看了《Java与模式》好像采用“饿汉式单例”同样可以解决这个问题:

public class Tst {
	public static void main(String[] args) {
		A.getInstance();
	}
}
class Glbl {
	static {
		System.out.println("In class GlblVars");
	}
	public static String log = "I love java.";
	public static A a = A.getInstance();
}
class A {
	static {
		System.out.println("In class A");
	}
	static int instanceNum = 0;
	private A() {
		instanceNum ++;
		int n = instanceNum;
		System.out.println(n +" create instance A");
		System.out.println(Glbl.log);
		System.out.println(n +" create instance A done");
	}
	private static A instance = new A();
	public static A getInstance() { return instance;}
}

 

 

结果:

In class A
1 create instance A
In class GlblVars
I love java.
1 create instance A done

 

0
1
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics