代码之家  ›  专栏  ›  技术社区  ›  Hary

抽象类中的Java延迟加载单例

  •  0
  • Hary  · 技术社区  · 6 年前

    我正在尝试用Java中的抽象类实现Singleton实例。我读过这样的书:把它当作懒汉来实现是最好的做法。我不能做到这一点,因为我不太习惯这种模式,甚至Java。

    1. 我不认为在构建实例时会出现延迟加载。

    这是我所拥有的,

    接口:

    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; }
    }
    

    public final class AndAppender extends AppenderBase implements IConditionAppender {
    
    private AndAppender()
    {
        super(new AndAppender())
    }
    
    @Override
    public String Append()
    {
        return " AND ";
    }
    

    }

    System.out.println(AndAppender.getInstance().Append());
    
    1 回复  |  直到 6 年前
        1
  •  1
  •   Maxim    6 年前

    AndAppender 可以实施

    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 ";
        }
    }
    

    同样的方法 OrAppender

    注: 此实现不是线程安全的。


    更简单的方法是使用 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());
    
        }
    }
    
        2
  •  1
  •   Zhou Hongbo    6 年前

    下面的代码可能对您有所帮助~

    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);
            }
        }
    }
    

    发件人: https://www.cnblogs.com/wang9192/p/3975748.html