2010-01-14 101 views
3

我想创建一个类的单个实例。我如何在Java中创建一个类的单个实例?Java类的单个实例

+6

'new MyClass()'once once once? – 2010-01-14 06:21:16

+2

OT - 引用了前面的问题:“我非常熟悉java编程语言” - girinie,说实话,我没有想到这个问题 - 你必须在攻击你的网上商店项目之前提高你的Java技能(http: //stackoverflow.com/questions/2055016/web-site-design-idea-closed)!至少你应该知道(主人?)GoF模式。 – 2010-01-14 08:33:01

回答

17

要创建一个类的真正单个实例(意味着在JVM级别的单例),您应该让您的类成为Java enum

public enum MyClass { 
    INSTANCE; 

    // Methods go here 
} 

单例模式使用静态状态,因此单元测试时通常会导致严重后果。

这在Joshua Bloch的Effective Java的第3项中有解释。

+0

确切地说,singleton只会在classloader级别,必须控制JVM中的所有类加载器才能够保证JVM级别的单例。 – pgras 2010-01-14 09:29:35

+0

我认为您会发现这是对枚举打算执行的操作的滥用。枚举适用于多个相关项目(例如一周中的几天),以便您可以使用类型安全的方式执行切换/比较等。它们不适用于类的单个实例。不管您如何实现它,单身人士都会因为不同的类加载器结构而变得复杂。 – Shane 2010-02-01 22:18:25

+0

@Shane,请参阅Effective Java。 Java枚举不仅仅是其他语言中可用的简单枚举。 – gpampara 2010-02-02 05:36:36

5

使用单例模式。

Singleton pattern

更新:

什么是单例模式? 单元素模式是用于限制类的实例化到一个对象

+1

-1显然..但他不想知道如何 – lexu 2010-01-14 06:20:43

+1

这就是为什么我添加了一个链接。在这里没有重复使用相同的信息 – 2010-01-14 06:21:56

+0

没有看到链接,您的编辑和我的评论必须是异步的。我已经删除了-1 – lexu 2010-01-14 06:23:33

10

非常基本单的设计模式。

public class Singleton { 
    private static Singleton instance; 

    static { 
    instance = new Singleton(); 
    } 

    private Singleton() { 
    // hidden constructor 
    }  

    public static Singleton getInstance() { 
    return instance; 
    } 
} 

您还可以使用懒人支架模式以及

public class Singleton { 

    private Singleton() { 
    // hidden constructor 
    } 

    private static class Holder { 
    static final Singleton INSTANCE = new Singleton(); 
    } 

    public static Singleton getInstance() { 
    return Holder.INSTANCE; 
    } 
} 

,直到您访问的getInstance()这个版本将无法创建单例的实例,但由于方式的JVM /类加载器处理内部类的创建,保证只有构造函数调用一次。

+1

说明: 我不认为没有办法限制构造函数的执行。 解决的办法是:使构造函数为私有 - 这样任何人都无法从外部调用它。 使用静态函数初始化对象的唯一实例 - 如果它是NULL,则在内部调用构造函数。 – effkay 2010-01-14 06:34:45

+0

我对此的唯一改进是单例的延迟初始化。 – 2010-01-14 06:48:39

+1

为什么静态阻止?您可以在声明它的同一行上初始化实例。 @Taylor L您不一定总是需要懒惰的init,这取决于应用程序的其余部分及其引导要求。 – 2010-01-14 09:15:46

1
In Java, how can we have one instance of the BrokerPacket class in two threads? 

以便所有线程更新都将不同的BrokerLocation存储在一个位置数组中。 例如:

class BrokerLocation implements Serializable { 
    public String broker_host; 
    public Integer broker_port; 

    /* constructor */ 
    public BrokerLocation(String host, Integer port) { 
     this.broker_host = host; 
     this.broker_port = port; 
    } 
} 


public class BrokerPacket implements Serializable { 
    public static BrokerLocation locations[]; 

}