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

抽象类中的Java延迟加载单例,java,singleton,lazy-loading,Java,Singleton,Lazy Loading,我正在尝试用Java中的抽象类实现单例实例。我读过这样的书,认为将其作为懒汉来实现是最佳实践。我无法做到这一点,因为我不太习惯这种模式,甚至不太习惯Java getInstance()总是空的,我不知道为什么 我认为,在构建实例时,这不会导致延迟加载 除此之外,欢迎发表任何其他评论,因为我对Java完全陌生,以前在c#上工作过 这是我的 界面: public interface IConditionAppender{ public String Append(); } 摘要 publi

我正在尝试用Java中的抽象类实现单例实例。我读过这样的书,认为将其作为懒汉来实现是最佳实践。我无法做到这一点,因为我不太习惯这种模式,甚至不太习惯Java

  • getInstance()总是空的,我不知道为什么
  • 我认为,在构建实例时,这不会导致延迟加载
  • 除此之外,欢迎发表任何其他评论,因为我对Java完全陌生,以前在c#上工作过
  • 这是我的

    界面:

    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操作类的Singleton
    private static final And appender instance=new And appender()
    的工作原理是一样的吗?不。它不是惰性的,
    And appender
    的实例将在类加载时创建,而不是在第一次使用
    getInstance()请求时创建
    method
    private static final and appender instance=new and appender()
    的工作原理是一样的,对吗?不。它不是惰性的,它的
    and appender
    的实例将在类加载时创建,而不是在第一次需要时创建