2015-09-23 3 views
0

У меня есть простой интерфейс:Есть ли способ создать универсальный синглтон для универсального класса, который имеет метод идентификации?

public interface Constraint<T> { 
    T constrain(T unconstrainedValue); 
} 

, и я хочу, чтобы создать UNCONSTRAINED синглтон, который можно использовать для любого типа ... есть ли способ сделать это без создания отдельных объектов для каждого типа?

static class NoConstraint<T> implements Constraint<T> { 
    @Override public T constrain(T unconstrainedValue) { return unconstrainedValue; } 
} 
+0

Почему у вашей модели класса NoConstraint есть статический модификатор? Предполагается, что это внутренний класс? – alainlompo

ответ

3

Вы можете сделать это с использованием небезопасных слепки, которые вы знаете, будет в безопасности:

static class NoConstraint<T> implements Constraint<T> { 
    private static final Constraint rawInstance = new NoConstraint(); 

    public static <T> Constraint<T> instance() { 
     @SupressWarnings("unchecked") 
     Constraint<T> generic = rawInstance; 
     return generic; 
    } 

    @Override 
    public T constrain(T unconstrainedValue) { 
     return unconstrainedValue; 
    } 
} 

Излишне говорить, что вы должны сделать это, только если вы доказали себе, что это всегда безопасно (который в этом случае, вероятно, довольно легко сделать).

Это не необычный трюк в подобных ситуациях. Например, Collections.emptyList (и аналогичные методы в этом классе) используют эту технику.

Заметим также, что T в методе instance() является отличается от T в Constraint<T>, несмотря на то, что они разделяют то же имя. T Constraint доступен только в контексте экземпляра, а не в статическом контексте, поэтому мы должны объявить общий параметр для статического метода. В большинстве случаев затенение имен, подобных этому, опасно; в таких случаях я считаю это полезным, как наглядное напоминание о том, что и T s тесно связаны с типичным пользователем.

+1

return T не будет работать, потому что вам нужно вернуть объект, а не тип. возможно, вы имеете в виду возвращение unconstrainedValue. Та же проблема возникает в исходном вопросе. – WillShackleford

+0

@WillShackleford Ах да, спасибо - я только что скопировал этот бит. :) Исправит это. – yshavit

+0

Вы должны добавить частный конструктор, чтобы класс не мог быть создан в другом месте – Chirlo

Смежные вопросы