public static 类名 getInstance(){//由于外部无法通过对象访问该方法,因此将该方法声明为静态
return 变量名;
}
}
public class Single{
private Single(){}
private static final Single s = new Single();
public static Single getInstance(){
return s;
}
}
2.懒汉式:相对于饿汉式,懒汉式延迟对象的加载,饿汉式是当类加载的时候,本类对象就产生
而懒汉式当调用getInstance()方法的时候才产生对象
/*
* 单例模式懒汉式,对象的延迟加载
* 安全的,高效的应用
*
*
*
*/
public class Single {
private Single(){}
private static Single s = null;
public static Single getInstance(){
if( s == null)
s = new Single();
}
return s;
}
}
多线程启动懒汉式可能会产生多个对象,不能保证对象唯一
分析:
// Thread-0
public static Single getInstance(){
if( s == null){
//1.CPU切换到Thread-0,由于s==null为true,进入if
s = new Single();//3.CPU切换回Thread-0,此时new Single()(Single@654fb)
}
return s;//4.Thread-0执行return 返回s指向的对象
}
// Thread-1
public static Single getInstance(){
if( s == null){
//2.CPU切换到Thread-1,由于s==null为true,进入if
s = new Single();//5CPU切换到Thread-1,此时new Single()(Single@76fc)
}
}
return s;//6.Thread-1执行return 返回s指向的对象
}
最终解决方案:
public class Single {
private Single(){}
private static Single s = null;
public static Single getInstance(){
if(s == null){//当其中一个线程创建完本类的对象后,另外一个线程在执行getInstance()方法
//不需要走同步代码,减少判断是否有锁,直接return
synchronized(Single.class){
if( s == null)//保证多个线程执行getInstance()方法,创建的对象的唯一
s = new Single();
}
}
*/
public abstract class Animal {
public abstract void eat();
}
public class Cat extends Animal{
public void eat(){
System.out.println("猫在吃鱼");
}
}
public class Dog extends Animal {
public void eat() {
System.out.println("狗吃骨头");
}
}
/*
* 工厂类,生产对象,创建对象
* 只创建动物对象,其他对象不做
*/
public class Factory {
//定义方法,创建动物对象
public static Animal createAnimal(String name){
if("cat".equals(name))
return new Cat();
else if ("dog".equals(name))
return new Dog();
return null;
}
}
public class Test {
public static void main(String[] args) {
//直接调用工厂类的静态方法,传递参数,获取对象
Animal a = Factory.createAnimal("cat");
a.eat();
a = Factory.createAnimal("dog");
a.eat();
a = Factory.createAnimal("car");
a.eat();
}
}
b.工厂中使用反射:
/*
优点:避免写一堆if,else语句,根据类的完全限定名来创建对象
缺点:由于createAnimal方法需要接收类名,无法控制用户传递过来的类是非动物类
*/
public class Factory {
public static Animal createAnimal(String className)
throws ClassNotFoundException, InstantiationException,
IllegalAccessException {
Animal a;
try {
/*
* 工厂方法设计模式:
* 将每个对象,交给了各自工厂去创建
* 有猫工厂,狗工厂,作用就是建立对象
*/
public class Test {
public static void main(String[] args) {
Factory f = new CatFactory();
Animal a = f.createAnimal();
a.eat();
f = new DogFactory();
a = f.createAnimal();
a.eat();
}
}