java—如何在泛型中实现空对象模式?

k2arahey  于 2021-07-09  发布在  Java
关注(0)|答案(3)|浏览(815)

我喜欢空对象模式的想法,并强迫我使用它,直到它真正感觉正常和良好。目前我不知道如何在泛型类型中使用它。我知道定义第二个泛型类型并传入类来构造默认对象的可能性,但是对于这种模式来说,这感觉开销太大了。有什么好办法吗?

public class GenericExample<T> {
    public static final GenericExample NULL = ???;

    private T attribute;

    public GenericExample(T attribute) {
        this.attribute = attribute;
    }
}

public class HoldGeneric {
    private GenericExample<String> name = GenericExample.NULL;

    public initLater(String name) {
        this.name = new GenericExample<String>(name);
    }
}
bsxbgnwa

bsxbgnwa1#

您可以按照jdk所做的操作,使用静态方法来推断泛型类型并执行未检查的强制转换。 java.util.Collections 为空列表和集实现空对象。在java预泛型中,有一个公共静态字段。

public static final List EMPTY_LIST = new EmptyList();

后泛型(post-generics):现在有一些静态方法可以推断泛型类型并执行未检查的强制转换,以便将其强制转换为正确的类型。类型其实并不重要,因为集合是空的,但它使编译器感到高兴。

@SuppressWarnings("unchecked")
public static final <T> List<T> emptyList() {
    return (List<T>) EMPTY_LIST;
}
y0u0uwnf

y0u0uwnf2#

没有通过 T 没有办法正确实施。你能做的最接近的,滥用类型擦除,将是:

class GenericExample<T>
{
  private static final GenericExample<Object> NULL = new GenericExample<Object>(); 

  public static <T> GenericExample<T> nil()
  {
    @SuppressWarnings("unchecked")
    final GenericExample<T> withNarrowedType = (GenericExample<T>)NULL;
    return withNarrowedType;
  }
}

然而,你必须接受这一点 GenericExample.<Apple>nil() 会和 GenericExample.<Orange>nil() .

kmbjn2e3

kmbjn2e33#

根据我对你的问题的理解,我同意以下观点。

public class GenericExample<T> {

    public static final GenericExample<?> NULL = new GenericExample<Object>(new Object()) {
        public void print() {
        }
    };

    private T attribute;

    public GenericExample(T attribute) {
        this.attribute = attribute;
    }

    public void print() {
        System.out.print(attribute.toString());
    }

    @SuppressWarnings("unchecked")
    public static <X> GenericExample<X> nil() {
        return (GenericExample<X>) NULL;
    }
}

public class Test {

    private static GenericExample<String> name = GenericExample.nil();

    public static void main(String[] args) {
        String x = "blah";
        name.print();
        if (name == GenericExample.NULL) {
            name = new GenericExample<String>(x);
        }
        name.print();
    }
}

相关问题