В зависимости от использования существует несколько "корректных" ответов.
С тех пор java5 лучший способ сделать это должен использовать перечисление:
public enum Foo {
INSTANCE;
}
Пред java5, самый простой случай:
public final class Foo {
private static final Foo INSTANCE = new Foo();
private Foo() {
if (INSTANCE != null) {
throw new IllegalStateException("Already instantiated");
}
}
public static Foo getInstance() {
return INSTANCE;
}
public Object clone() throws CloneNotSupportedException{
throw new CloneNotSupportedException("Cannot clone instance of this class");
}
}
Позволяют нам пробежаться через код. Во-первых, Вы хотите, чтобы класс был окончательным. В этом случае я использовал final
ключевое слово, чтобы позволить пользователям знать, что это является окончательным. Тогда необходимо сделать конструктора частным для предотвращения пользователей для создания их собственного Foo. Выдача исключения от конструктора предотвращает пользователей для использования отражения для создания второго Foo. Тогда Вы создаете private static final Foo
поле для содержания единственного экземпляра, и public static Foo getInstance()
метод для возврата его. Спецификация Java удостоверяется, что конструктора только вызывают, когда класс сначала используется.
, Когда Вы имеете очень большой объект или тяжелый код конструкции И также имеете другие доступные статические методы или поля, которые могли бы использоваться, прежде чем экземпляр необходим, тогда и только тогда необходимо использовать ленивую инициализацию.
можно использовать private static class
для загрузки экземпляра. Код был бы тогда похож:
public final class Foo {
private static class FooLoader {
private static final Foo INSTANCE = new Foo();
}
private Foo() {
if (FooLoader.INSTANCE != null) {
throw new IllegalStateException("Already instantiated");
}
}
public static Foo getInstance() {
return FooLoader.INSTANCE;
}
}
, Так как строка private static final Foo INSTANCE = new Foo();
только выполняется, когда класс, FooLoader на самом деле используется, это заботится о ленивом инстанцировании и является им, гарантировал, что был ориентирован на многопотоковое исполнение.
, Когда Вы также хотите быть в состоянии сериализировать свой объект, необходимо удостовериться, что десериализация не создаст копию.
public final class Foo implements Serializable {
private static final long serialVersionUID = 1L;
private static class FooLoader {
private static final Foo INSTANCE = new Foo();
}
private Foo() {
if (FooLoader.INSTANCE != null) {
throw new IllegalStateException("Already instantiated");
}
}
public static Foo getInstance() {
return FooLoader.INSTANCE;
}
@SuppressWarnings("unused")
private Foo readResolve() {
return FooLoader.INSTANCE;
}
}
метод readResolve()
удостоверится, что единственный экземпляр будет возвращен, даже когда объект был сериализирован в предыдущем выполнении Вашей программы.
Вот канал yahoo , который я построил, который собирает сообщения блога, связанные с Castle. Теперь доступно для чтения через http://www.castleproject.org/community/blogs.aspx
Castleproject.org содержит много информации о конфигурации xml и внутреннем устройстве
Майк Хэдлоу как кое-что хорошее о замке Виндзор, включая мультиарендность
http://mikehadlow.blogspot.com/
Colin G