Java构造方private吗,java中使用private构造方法不能实现单例模式

众所周知,一般使用java实现单例模式有两种方法,分别为急切式(饥饿式)和双重加锁式,急切式就是在声明时即创建,这样在类加载时就已经创建好了,即时我们可能并不不需要它,它的生命周期是永久的,造成内存泄漏的可能!第二种方式是lazy的,只有在使用时创建,实现了延迟加载。代码为

1.急切式

class Singleton {

private final static Singleton instance = new Singleton();

private Singleton(){

}

public static Singleton getInstance() {

return instance;

}

}

2. 双重加锁式

class Singleton {

private volatile static Singleton instance = null;

private Singleton(){

}

public static Singleton getInstance() {

if (instance == null) {

synchronized(Singleton.class) {

if (instance == null) {

instance = new Singleton();

}

}

}

return instance;

}

}

还有一种方法是使用内部类的方法,这主要为克服方法1中的问题,既能实现延迟加载,又能保证线程安全,而且性能不错。代码为:

class Singleton {

private Singleton() {

}

private static class Holder {

private static final Singleton INSTANCE = new Singleton();

}

public static Singleton getInstance() {

return Holder.INSTANCE;

}

}

以上方法都是通过使用private构造方法来阻止外部直接创建对象,但如果使用反射机制,则不能保证实例的唯一性了!!!

public class SingletonDemo {

//@SuppressWarnings("unchecked")

//public static T newInstance(Class> cl) {

// T t = null;

// try {

// t = (T)cl.newInstance(); /* 只能调用public构造方法 */

// } catch(Exception e) {

// e.printStackTrace();

// }

// return t;

//}

@SuppressWarnings("unchecked")

public static T newInstance(Class> cl) {

T t = null;

try {

Constructor> constructor = cl.getDeclaredConstructor();

constructor.setAccessible(true);

t = (T)constructor.newInstance();

} catch(Exception e) {

e.printStackTrace();

}

return t;

}

@SuppressWarnings("unchecked")

public static T newInstance(Class> cl, Class>...args) {

T t = null;

try {

Constructor> constructor = cl.getDeclaredConstructor(args);

constructor.setAccessible(true);

t = (T)constructor.newInstance("name", 1);

} catch(Exception e) {

e.printStackTrace();

}

return t;

}

public static void main(String[] args) {

Singleton instance = Single.INSTANCE;

Singleton s1 = newInstance(Singleton.class, String.class, int.class);

Singleton s2 = newInstance(Singleton.class, String.class, int.class);

//Tmp t1 = newInstance(Tmp.class);

//Tmp t2 = newInstance(Tmp.class);

//System.out.println(s1 == s2);

//System.out.println(t1 == t2);

}

}

Joshua Bloch (Effect java 作者)提出一种新的方法实现单例模式,就是使用Enum(其实也是类,一种特殊的类,构造方法必须是private ,final的)!如下:

enum Singleton {

INSTANCE;

public void sayHi() {

System.out.println("Hi");

}

}

这样当试图通过反射机制创建对象时,会抛出异常!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值