避免在通用工厂中投射
Avoid cast in generic factories
假设我有一个如下所示的 class 结构:
public abstract class Interval<I extends Interval<?>> {
public static final IntervalFactory<? extends Interval<?>> factory = null;
// some variables and methods
}
public class Week extends Interval<Week> {
public static final IntervalFactory<Week> factory = new WeekFactory();
// some variables and methods
}
public interface IntervalFactory<I extends Interval> {
I containing(LocalDate date);
List<I> containing(LocalDate startDate, LocalDate endDate);
}
public class WeekFactory implements IntervalFactory<Week> {
@Override
public Week containing(LocalDate date) {
// implementation
}
@Override
public List<Week> containing(LocalDate startDate, LocalDate endDate) {
// implementation
}
}
现在我有一个使用这些间隔和工厂的 class:
public class SomeClass<I extends Interval<?>> {
private final IntervalFactory<I> intervalFactory;
public DistributorForSlowQuantifier() {
this.intervalFactory = (IntervalFactory<I>) I.factory;
}
public Map<I, Double> distribute(double value) {
// implementation
}
}
如果 class 需要从类型变量创建实例,这是解决问题的正确方法吗?
在 SomeClass
构造函数中是否有绕过转换的方法?
显而易见的事情是行不通的——在 SomeClass
中使用通配符作为 intervalFactory 的类型参数会丢失所有类型信息,工厂是静态的,所以我不能将 I
用作类型参数,如果我不将它们标记为静态,我需要一个 I 的实例来访问工厂...
强制转换是绝对安全的,只要Interval实现选择“对应”的工厂即可,但感觉还是……不对。
SomeClass
构造函数中的转换甚至不起作用。它将始终使用 Interval.factory
,无论它是否对应于您想要的工厂类型。 I.factory
并没有按照你的想法去做。
迄今为止最常见和最明智的方法:将适当的工厂传递给构造函数。您可以使用静态导入和静态工厂方法为此添加一些语法糖,使其看起来像例如new DistributorForSlowQuantifier(days())
之类的。还有其他更复杂和混乱的解决方法,但考虑到所有因素,它们更糟糕。
假设我有一个如下所示的 class 结构:
public abstract class Interval<I extends Interval<?>> {
public static final IntervalFactory<? extends Interval<?>> factory = null;
// some variables and methods
}
public class Week extends Interval<Week> {
public static final IntervalFactory<Week> factory = new WeekFactory();
// some variables and methods
}
public interface IntervalFactory<I extends Interval> {
I containing(LocalDate date);
List<I> containing(LocalDate startDate, LocalDate endDate);
}
public class WeekFactory implements IntervalFactory<Week> {
@Override
public Week containing(LocalDate date) {
// implementation
}
@Override
public List<Week> containing(LocalDate startDate, LocalDate endDate) {
// implementation
}
}
现在我有一个使用这些间隔和工厂的 class:
public class SomeClass<I extends Interval<?>> {
private final IntervalFactory<I> intervalFactory;
public DistributorForSlowQuantifier() {
this.intervalFactory = (IntervalFactory<I>) I.factory;
}
public Map<I, Double> distribute(double value) {
// implementation
}
}
如果 class 需要从类型变量创建实例,这是解决问题的正确方法吗?
在 SomeClass
构造函数中是否有绕过转换的方法?
显而易见的事情是行不通的——在 SomeClass
中使用通配符作为 intervalFactory 的类型参数会丢失所有类型信息,工厂是静态的,所以我不能将 I
用作类型参数,如果我不将它们标记为静态,我需要一个 I 的实例来访问工厂...
强制转换是绝对安全的,只要Interval实现选择“对应”的工厂即可,但感觉还是……不对。
SomeClass
构造函数中的转换甚至不起作用。它将始终使用 Interval.factory
,无论它是否对应于您想要的工厂类型。 I.factory
并没有按照你的想法去做。
迄今为止最常见和最明智的方法:将适当的工厂传递给构造函数。您可以使用静态导入和静态工厂方法为此添加一些语法糖,使其看起来像例如new DistributorForSlowQuantifier(days())
之类的。还有其他更复杂和混乱的解决方法,但考虑到所有因素,它们更糟糕。