抽象类中的Java延迟加载单例
我正在尝试用Java中的抽象类实现单例实例。我读过这样的书,认为将其作为懒汉来实现是最佳实践。我无法做到这一点,因为我不太习惯这种模式,甚至不太习惯Java抽象类中的Java延迟加载单例,java,singleton,lazy-loading,Java,Singleton,Lazy Loading,我正在尝试用Java中的抽象类实现单例实例。我读过这样的书,认为将其作为懒汉来实现是最佳实践。我无法做到这一点,因为我不太习惯这种模式,甚至不太习惯Java getInstance()总是空的,我不知道为什么 我认为,在构建实例时,这不会导致延迟加载 除此之外,欢迎发表任何其他评论,因为我对Java完全陌生,以前在c#上工作过 这是我的 界面: public interface IConditionAppender{ public String Append(); } 摘要 publi
public interface IConditionAppender{
public String Append();
}
摘要
public abstract AppenderBase {
private static IConditionAppender instance;
protected AppenderBase(IConditionAppender instance)
{
this.instance = instance;
}
public static IConditionAppender getInstance(){ return instance; }
}
System.out.println(AndAppender.getInstance().Append());
实施
public final class AndAppender extends AppenderBase implements IConditionAppender {
private AndAppender()
{
super(new AndAppender())
}
@Override
public String Append()
{
return " AND ";
}
}
测试
public abstract AppenderBase {
private static IConditionAppender instance;
protected AppenderBase(IConditionAppender instance)
{
this.instance = instance;
}
public static IConditionAppender getInstance(){ return instance; }
}
System.out.println(AndAppender.getInstance().Append());
下面是如何实现
和appender
public final class AndAppender implements ConditionAppender {
private static final AndAppender instance;
public static AndAppender getInstance() {
if (instance == null)
instance = new AndAppender();
return instance;
}
private AndAppender() { }
@Override
public String append() {
return " AND ";
}
}
对于或出现的等,采用相同的方法
注意:此实现不是线程安全的
更简单的方法是使用Enum
,默认情况下它是单例的,可以实现接口
public enum Appender implements ConditionAppender {
AND(" AND "), OR(" OR ");
final String operation;
Appender(String operation) {
this.operation = operation;
}
@Override
public String append() {
return operation;
}
public static void main(String[] args) {
System.out.println(AND.append());
System.out.println(OR.append());
}
}
下面是如何实现和appender
public final class AndAppender implements ConditionAppender {
private static final AndAppender instance;
public static AndAppender getInstance() {
if (instance == null)
instance = new AndAppender();
return instance;
}
private AndAppender() { }
@Override
public String append() {
return " AND ";
}
}
对于或出现的等,采用相同的方法
注意:此实现不是线程安全的
更简单的方法是使用Enum
,默认情况下它是单例的,可以实现接口
public enum Appender implements ConditionAppender {
AND(" AND "), OR(" OR ");
final String operation;
Appender(String operation) {
this.operation = operation;
}
@Override
public String append() {
return operation;
}
public static void main(String[] args) {
System.out.println(AND.append());
System.out.println(OR.append());
}
}
下面的代码可能对您有所帮助~
public abstract class AbstractSingleton {
private static Map<String, AbstractSingleton> registryMap = new HashMap<String, AbstractSingleton>();
AbstractSingleton() throws SingletonException {
String clazzName = this.getClass().getName();
if (registryMap.containsKey(clazzName)) {
throw new SingletonException("Cannot construct instance for class " + clazzName + ", since an instance already exists!");
} else {
synchronized (registryMap) {
if (registryMap.containsKey(clazzName)) {
throw new SingletonException("Cannot construct instance for class " + clazzName + ", since an instance already exists!");
} else {
registryMap.put(clazzName, this);
}
}
}
}
@SuppressWarnings("unchecked")
public static <T extends AbstractSingleton> T getInstance(final Class<T> clazz) throws InstantiationException, IllegalAccessException {
String clazzName = clazz.getName();
if (!registryMap.containsKey(clazzName)) {
synchronized (registryMap) {
if (!registryMap.containsKey(clazzName)) {
T instance = clazz.newInstance();
return instance;
}
}
}
return (T) registryMap.get(clazzName);
}
public static AbstractSingleton getInstance(final String clazzName)
throws ClassNotFoundException, InstantiationException, IllegalAccessException {
if (!registryMap.containsKey(clazzName)) {
Class<? extends AbstractSingleton> clazz = Class.forName(clazzName).asSubclass(AbstractSingleton.class);
synchronized (registryMap) {
if (!registryMap.containsKey(clazzName)) {
AbstractSingleton instance = clazz.newInstance();
return instance;
}
}
}
return registryMap.get(clazzName);
}
@SuppressWarnings("unchecked")
public static <T extends AbstractSingleton> T getInstance(final Class<T> clazz, Class<?>[] parameterTypes, Object[] initargs)
throws SecurityException, NoSuchMethodException, IllegalArgumentException,
InvocationTargetException, InstantiationException, IllegalAccessException {
String clazzName = clazz.getName();
if (!registryMap.containsKey(clazzName)) {
synchronized (registryMap) {
if (!registryMap.containsKey(clazzName)) {
Constructor<T> constructor = clazz.getConstructor(parameterTypes);
T instance = constructor.newInstance(initargs);
return instance;
}
}
}
return (T) registryMap.get(clazzName);
}
static class SingletonException extends Exception {
private static final long serialVersionUID = -8633183690442262445L;
private SingletonException(String message) {
super(message);
}
}
}
公共抽象类AbstractSingleton{
私有静态映射注册表Map=newhashmap();
AbstractSingleton()抛出SingletonException{
字符串clazzName=this.getClass().getName();
if(registryMap.containsKey(clazzName)){
抛出新的SingletonException(“无法为类“+clazzName+”构造实例,因为实例已经存在!”);
}否则{
已同步(注册表映射){
if(registryMap.containsKey(clazzName)){
抛出新的SingletonException(“无法为类“+clazzName+”构造实例,因为实例已经存在!”);
}否则{
registryMap.put(clazzName,this);
}
}
}
}
@抑制警告(“未选中”)
publicstatict getInstance(final类clazz)抛出instanceionException、IllegalAccessException{
字符串clazzName=clazz.getName();
if(!registryMap.containsKey(clazzName)){
已同步(注册表映射){
if(!registryMap.containsKey(clazzName)){
T instance=clazz.newInstance();
返回实例;
}
}
}
return(T)registryMap.get(clazzName);
}
公共静态抽象单例getInstance(最终字符串clazzName)
抛出ClassNotFoundException、InstanceionException、IllegalAccessException{
if(!registryMap.containsKey(clazzName)){
Class下面的代码可能会对您有所帮助~
public abstract class AbstractSingleton {
private static Map<String, AbstractSingleton> registryMap = new HashMap<String, AbstractSingleton>();
AbstractSingleton() throws SingletonException {
String clazzName = this.getClass().getName();
if (registryMap.containsKey(clazzName)) {
throw new SingletonException("Cannot construct instance for class " + clazzName + ", since an instance already exists!");
} else {
synchronized (registryMap) {
if (registryMap.containsKey(clazzName)) {
throw new SingletonException("Cannot construct instance for class " + clazzName + ", since an instance already exists!");
} else {
registryMap.put(clazzName, this);
}
}
}
}
@SuppressWarnings("unchecked")
public static <T extends AbstractSingleton> T getInstance(final Class<T> clazz) throws InstantiationException, IllegalAccessException {
String clazzName = clazz.getName();
if (!registryMap.containsKey(clazzName)) {
synchronized (registryMap) {
if (!registryMap.containsKey(clazzName)) {
T instance = clazz.newInstance();
return instance;
}
}
}
return (T) registryMap.get(clazzName);
}
public static AbstractSingleton getInstance(final String clazzName)
throws ClassNotFoundException, InstantiationException, IllegalAccessException {
if (!registryMap.containsKey(clazzName)) {
Class<? extends AbstractSingleton> clazz = Class.forName(clazzName).asSubclass(AbstractSingleton.class);
synchronized (registryMap) {
if (!registryMap.containsKey(clazzName)) {
AbstractSingleton instance = clazz.newInstance();
return instance;
}
}
}
return registryMap.get(clazzName);
}
@SuppressWarnings("unchecked")
public static <T extends AbstractSingleton> T getInstance(final Class<T> clazz, Class<?>[] parameterTypes, Object[] initargs)
throws SecurityException, NoSuchMethodException, IllegalArgumentException,
InvocationTargetException, InstantiationException, IllegalAccessException {
String clazzName = clazz.getName();
if (!registryMap.containsKey(clazzName)) {
synchronized (registryMap) {
if (!registryMap.containsKey(clazzName)) {
Constructor<T> constructor = clazz.getConstructor(parameterTypes);
T instance = constructor.newInstance(initargs);
return instance;
}
}
}
return (T) registryMap.get(clazzName);
}
static class SingletonException extends Exception {
private static final long serialVersionUID = -8633183690442262445L;
private SingletonException(String message) {
super(message);
}
}
}
公共抽象类AbstractSingleton{
私有静态映射注册表Map=newhashmap();
AbstractSingleton()抛出SingletonException{
字符串clazzName=this.getClass().getName();
if(registryMap.containsKey(clazzName)){
抛出新的SingletonException(“无法为类“+clazzName+”构造实例,因为实例已经存在!”);
}否则{
已同步(注册表映射){
if(registryMap.containsKey(clazzName)){
抛出新的SingletonException(“无法为类“+clazzName+”构造实例,因为实例已经存在!”);
}否则{
registryMap.put(clazzName,this);
}
}
}
}
@抑制警告(“未选中”)
publicstatict getInstance(final类clazz)抛出instanceionException、IllegalAccessException{
字符串clazzName=clazz.getName();
if(!registryMap.containsKey(clazzName)){
已同步(注册表映射){
if(!registryMap.containsKey(clazzName)){
T instance=clazz.newInstance();
返回实例;
}
}
}
return(T)registryMap.get(clazzName);
}
公共静态抽象单例getInstance(最终字符串clazzName)
抛出ClassNotFoundException、InstanceionException、IllegalAccessException{
if(!registryMap.containsKey(clazzName)){
类你在哪里调用附录库的参数化构造函数?@AshishkumarSingh,很抱歉错过了新关键字,它是在AndAppender类中构造的。为什么你的AndAppender类构造函数是私有的?使用这种设计,你不能创建或Appender
作为附录库
中的实例
静态字段我将被替换不要通过继承实现Singleton,因为它使用的静态字段和方法不涉及后期绑定。你应该为每个和/或操作类实现Singleton。你在哪里调用AppenderBase
?@AshishkumarSingh的参数化构造函数?很抱歉,错过了新关键字,它是在AndApp中构造的ender类为什么您的AndAppender类构造函数是私有的?使用此设计,您无法创建或Appender
,因为AppenderBase
中的实例
静态字段将被替换。不要通过继承实现Singleton,因为它使用的静态字段和方法不涉及后期绑定。您应该实现每个And/OR操作类的Singletonprivate static final And appender instance=new And appender()
的工作原理是一样的吗?不。它不是惰性的,And appender
的实例将在类加载时创建,而不是在第一次使用getInstance()请求时创建
methodprivate static final and appender instance=new and appender()
的工作原理是一样的,对吗?不。它不是惰性的,它的and appender
的实例将在类加载时创建,而不是在第一次需要时创建