当前位置: 首页 > 知识库问答 >
问题:

如何用恰当的方式写一个单字?

微生旻
2023-03-14

今天,在我的面试中,一个面试官让我写一个单件课。我的回答是

public class Singleton {

    private static Singleton ref;

    private Singleton() {
    }

    public static Singleton getInstance() {
        if (ref == null) {
            ref = new Singleton();
        }
        return ref;
    }
}

突然,他告诉我这是写这门课的老方法。有谁能告诉我他为什么那样说。

共有3个答案

扈德容
2023-03-14

你可以做

public enum Singleton {
    INSTANCE;
}

对于没有实例的实用程序类

public enum Utility {
     ;

     public static void method();
}
翟单弓
2023-03-14

最新标准解决方案:

>

  • 具有托管Bean/CDI的核心Java

    @ApplicationScoped
    public class MySingleton { ... }
    

    EJB Lite(JEE6)

    @Singleton
    public class MySingleton { ... }
    

    先前的建议(来自“有效的Java协议2”):

    >

  • 使用一个枚举,带有一个伪枚举常量,例如instance。数据字段和方法既可以是静态的,也可以是非静态的(实例)--两者的行为是等价的,因为只有一个实例

    优点:

    • 是的,这是一个单身。不可能通过任何机制(在任何JVM上的任何给定类加载器中)创建多个实例。
    • 单例初始化是线程安全的。

    缺点(与以上标准溶液相比):

    • 这个定义有点钝-'enum'外壳可能会误导没有经验的代码维护人员。这是一个小黑客,而不是枚举的初衷。
    • 实现通过抽象泄漏。违反了统一准入原则
      • 它不能通过注入工作-客户端必须知道它是针对精确枚举实例的单例代码
      • 客户端必须使用singleton.instance.someMethod()
      • 客户端不能(简单地)针对接口编写代码
      • 单实例对象与多实例对象之间的设计更改对客户端的影响

  • 夏季萌
    2023-03-14

    创建单例时,我首先想到的是enum。我一般使用枚举来实现单例:

    enum Singleton {
        INSTANCE;
    }
    

    使用枚举的一个好处是序列化。

    对于singleton类,您必须确保序列化和反序列化不会通过实现readresolve()方法创建新实例,而对于枚举则不是这样。

    使用class,您应该创建单例,如下所示:

    public final class Singleton implements Serializable {
        // For lazy-laoding (if only you want)
        private static class SingletonHolder {
            private static final Singleton INSTANCE = new Singleton();
        }
    
        private Singleton() {
            if (SingletonHolder.INSTANCE != null) {
                // throw Some Exception
            }
        }
    
        public static Singleton getInstance() {
            return SingletonHolder.INSTANCE;
        }
    
        // To avoid deserialization create new instance
        @SuppressWarnings("unused")
        private Singleton readResolve() {
            return SingletonHolder.INSTANCE;
        }
    }
    
     类似资料:
    • 问题内容: 今天,在我的采访中,一位面试官要求我写一个单例课程。我给我的答案是 突然他告诉我这是上课的老方法。谁能帮我他为什么这么说。 问题答案: 创建单例时,我想到的第一件事是。我通常使用enum实现单例: 使用枚举可为您带来的好处之一就是序列化。 对于单例类,您将必须确保通过实现方法来确保序列化和反序列化不会创建新实例,而enum并非如此。 使用类,您应该这样创建单例:

    • 如何写一个简单的公平锁模拟新的? 自定义不公平锁(我不确定它是否正确)

    • 我知道有几个类似这样的问题贴满了堆栈溢出,但没有一个真正回答我的问题。我正在编写一个helper-private bubbleDown方法来帮助我对公共静态HeapSort方法进行排序。 我知道这样做的目的是将自身视为最大堆,其数据从0(而不是1)开始。 a实际上不是按堆顺序排列的。 但是如果你反复“冒泡”每个非叶子节点,从最后一个开始,你最终会有一个合适的堆。 我已经写了这个算法,但我不确定这是

    • 你应该知道静态成员变量在创建对象实例之前就已经初始化了。C# 提供了静态初始化语法和静态构造函数对静态成员变量进行初始化。静态构造函数是一个比其他函数,变量,属性在没有访问之前就被执行的特殊函数。你可以使用这个函数初始化静态变量,完善单例模式,或者任何需要在类还没有被使用的必要工作。你不能使用构造函数,一些特殊 private 函数,或其他语法初始化静态变量。 和实例初始化一样,初始化语法是静态构

    • 输入要翻译的单词:Hello word in twist around:LohelLO 注:翻译的单词是这样形成的:直升机=OpterhelicCR后半部分的第一个字母大写:Opter前半部分的第一个字母小写:helic前半部分的最后一个字母大写:C后半部分的最后一个字母大写:R 这是我的密码。public static void main(string[]args){Scanner input=

    • 我使用java和Spring在一个应用服务器上工作,我想将许多方法调用分组到一个单元工作中。 一个特定的流程涉及创建一个新的业务相关实体,它涉及以下单独的操作/从我的应用服务器调用: 调用数据库 在内存缓存中调用 调用另一个应用程序服务器 我有一个单独的服务用于上面的每个操作,其中每个服务抛出一个特定的检查异常。目前,我正在one try catch块中调用上面的操作,并对我尝试回滚的每个异常使用