限制它的一种方法是使用静态重载工厂方法来构造对象。
public class Bla<T> {
private final T foo;
private final Class<T> fooClazz;
private Bla(T foo, Class<T> fooClazz) { // Must be private
this.foo = foo;
this.fooClazz = fooClazz;
}
@SuppressWarnings("unchecked")
public static <E extends Enum<E>> Bla<E> of(E foo) { // Caveat: Cannot handle null
return new Bla<>(foo, (Class<E>) foo.getClass());
}
public static Bla<Boolean> of(Boolean foo) {
return new Bla<>(foo, Boolean.class);
}
public static Bla<Integer> of(Integer foo) {
return new Bla<>(foo, Integer.class);
}
public static Bla<String> of(String foo) {
return new Bla<>(foo, String.class);
}
public static Bla<Supportable> of(Supportable foo) {
return new Bla<>(foo, Supportable.class);
}
public void do() {
// ...
}
// ...
}
它改变了调用者构造实例的方式,但实际上也简化了它,因为调用者不必传入Class<T>,例如
// With constructor (old way)
Bla<MyEnum> e2 = new Bla<>(MyEnum.A, MyEnum.class);
Bla<Boolean> b2 = new Bla<>(true, Boolean.class);
Bla<Integer> i2 = new Bla<>(42, Integer.class);
Bla<String> s2 = new Bla<>("", String.class);
Bla<Supportable> su2 = new Bla<>(supportable, Supportable.class);
// With static factory method (new way)
Bla<MyEnum> e1 = Bla.of(MyEnum.A);
Bla<Boolean> b1 = Bla.of(true);
Bla<Integer> i1 = Bla.of(42);
Bla<String> s1 = Bla.of("");
Bla<Supportable> su1 = Bla.of(supportable);
// Unsupported types are not allowed
Bla<Double> i1 = Bla.of(3.14); // Error: The method of(E) in the type Bla is not applicable for the arguments (double)
但是,与其在do() 方法中使用多路if 语句,不如使用子类。子类对调用者是隐藏的,因此它没有外部区别,但它消除了对多路if 语句/switch 语句的需要:
public abstract class Bla<T> {
private final T foo;
private final Class<T> fooClazz;
private Bla(T foo, Class<T> fooClazz) { // Must be private
this.foo = foo;
this.fooClazz = fooClazz;
}
@SuppressWarnings("unchecked")
public static <E extends Enum<E>> Bla<E> of(E foo) { // Caveat: Cannot handle null
return new Bla<>(foo, (Class<E>) foo.getClass()) {
@Override
public void do() {
// Do Enum specific code
}
};
}
public static Bla<Boolean> of(Boolean foo) {
return new Bla<>(foo, Boolean.class) {
@Override
public void do() {
// Do Boolean specific code
}
};
}
public static Bla<Integer> of(Integer foo) {
return new Bla<>(foo, Integer.class) {
@Override
public void do() {
// Do Integer specific code
}
};
}
public static Bla<String> of(String foo) {
return new Bla<>(foo, String.class) {
@Override
public void do() {
// Do String specific code
}
};
}
public static Bla<Supportable> of(Supportable foo) {
return new Bla<>(foo, Supportable.class) {
@Override
public void do() {
foo.doSpecific(this);
}
};
}
public abstract void do(); // Is now abstract
// ...
}
如果您愿意,当然可以创建(私有)静态嵌套类或(包私有)顶级类,而不是匿名类。
使用子类允许在多个方法中执行fooClass 特定的操作。如果您只有一种方法,则可以改用 lambda 表达式和/或方法引用:
public class Bla<T> {
private final T foo;
private final Class<T> fooClazz;
private final Consumer<Bla<T>> doImpl;
private Bla(T foo, Class<T> fooClazz, Consumer<Bla<T>> doImpl) { // Must be private
this.foo = foo;
this.fooClazz = fooClazz;
this.doImpl = doImpl;
}
@SuppressWarnings("unchecked")
public static <E extends Enum<E>> Bla<E> of(E foo) { // Caveat: Cannot handle null
return new Bla<>(foo, (Class<E>) foo.getClass(), bla -> {
// Do Enum specific code
});
}
public static Bla<Boolean> of(Boolean foo) {
return new Bla<>(foo, Boolean.class, bla -> {
// Do Boolean specific code
});
}
public static Bla<Integer> of(Integer foo) {
return new Bla<>(foo, Integer.class, bla -> {
// Do Integer specific code
});
}
public static Bla<String> of(String foo) {
return new Bla<>(foo, String.class, bla -> {
// Do String specific code
});
}
public static Bla<Supportable> of(Supportable foo) {
return new Bla<>(foo, Supportable.class, foo::doSpecific);
}
public void do() {
doImpl.accept(this);
}
// ...
}