我喜欢null object pattern的想法并强迫我使用它,直到它真的感觉正常和好。目前我没有看到如何在泛型类型中使用它。我知道定义第二个泛型类型并传入类来构造一个默认对象的可能性,但这对于这个模式来说真的太多了。有好办法吗?
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);
}
}
答案 0 :(得分:3)
您可以按照JDK的说法进行操作,并使用静态方法推断泛型类型并执行未经检查的强制转换。
java.util.Collections
为空列表和集实现Null对象。在Java Pre-generics中,有一个公共静态字段。
public static final List EMPTY_LIST = new EmptyList();
发布泛型: 现在有一些静态方法可以推断泛型类型并执行未经检查的转换,以便将其强制转换为正确的类型。该类型并不重要,因为集合是空的,但它使编译器感到高兴。
@SuppressWarnings("unchecked")
public static final <T> List<T> emptyList() {
return (List<T>) EMPTY_LIST;
}
答案 1 :(得分:2)
根据我对你的问题的理解,我会选择以下内容。
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();
}
}
答案 2 :(得分:1)
没有传递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()
相同。