如何将非通用接口扩展为通用接口?
How can I extend a non generic interface into a generic one?
我正在尝试扩展 TemporalAdjuster
以便看起来像
public interface TypedTemporalAdjuster<T extends Temporal & Comparable<? super T>> {
T adjustInto(T temporal);
}
当我尝试直接扩展基本接口时,
public interface TypedTemporalAdjuster<T extends Temporal & Comparable<? super T>>
extends TemporalAdjuster {
T adjustInto(T temporal);
}
我收到一个错误。
...java: name clash: ... have the same erasure, yet neither overrides the other
有什么办法吗?
到目前为止,我做到了。
public interface TypedTemporalAdjuster<T extends Temporal & Comparable<? super T>> { //extends TemporalAdjuster {
static <T extends Temporal & Comparable<? super T>> TypedTemporalAdjuster<T> of(
final Class<T> temporalClass, final TemporalAdjuster temporalAdjuster) {
return temporal -> temporalClass.cast(temporalAdjuster.adjustInto(temporalClass.cast(temporal)));
}
T adjustInto(T temporal);
}
您不能覆盖具有更严格参数的方法,即 T adjustInto(T temporal);
不会覆盖 Temporal adjustInto(Temporal temporal);
,因为参数类型 T
比 Temporal
更严格。所以你现在有两个名称为 adjustInto
的方法,但是由于类型擦除,参数类型在字节码级别上是相同的,因为 T extends Temporal & Comparable<? super T>
被擦除为 Temporal
.
您可以通过将声明更改为
来解决这个问题
public interface TypedTemporalAdjuster<T extends Comparable<? super T> & Temporal>
extends TemporalAdjuster {
T adjustInto(T temporal);
}
那时,语义相同的 T extends Comparable<? super T> & Temporal
被删除为 Comparable
而不是 Temporal
。您还可以使用 T extends Object & Comparable<? super T> & Temporal
,它会被擦除为 Object
(通常,此类知识仅在您需要与 pre-Generics 代码兼容时才有意义)。
然而,根本问题仍然存在,adjustInto(T temporal);
不会覆盖 adjustInto(Temporal temporal);
,因为 T
是一个更具限制性的参数,所以现在,该接口不再是功能接口,因为它有两个抽象方法。
TemporalAdjuster
的子接口必须提供其所有操作,包括接受任何 Temporal
的 adjustInto
。所以你只能做
public interface TypedTemporalAdjuster<T extends Temporal & Comparable<? super T>>
extends TemporalAdjuster {
static <T extends Temporal & Comparable<? super T>> TypedTemporalAdjuster<T> of(
final Class<T> temporalClass, final TemporalAdjuster temporalAdjuster) {
return temporal -> temporalClass.cast(temporalAdjuster.adjustInto(temporal));
}
@Override T adjustInto(Temporal temporal);
}
然而,这种包装调整器不能确保正确的参数,只能隐藏在运行时仍然可能失败的类型转换。但是看起来您正在尝试解决此处不存在的问题,因为您可以简单地在时间上使用 with
方法来获得类型安全的操作,例如
TemporalAdjuster a = TemporalAdjusters.lastDayOfMonth();
LocalDate date1 = LocalDate.now(), date2 = date1.with(a);
LocalDateTime dateTime1 = LocalDateTime.now(), dateTime2 = dateTime1.with(a);
ZonedDateTime zoned1 = ZonedDateTime.now(), zoned2 = zoned1.with(a);
这比你的包装器更强大,就像你做的那样,例如
TemporalAdjuster a = TemporalAdjusters.ofDateAdjuster(date -> date.plusDays(1));
ZonedDateTime zoned1 = ZonedDateTime.now(), zoned2 = zoned1.with(a);
根据 LocalDate
操作,您只需定义一次操作,而它通过即时转换而不是转换来适用于其他时间。
我正在尝试扩展 TemporalAdjuster
以便看起来像
public interface TypedTemporalAdjuster<T extends Temporal & Comparable<? super T>> {
T adjustInto(T temporal);
}
当我尝试直接扩展基本接口时,
public interface TypedTemporalAdjuster<T extends Temporal & Comparable<? super T>>
extends TemporalAdjuster {
T adjustInto(T temporal);
}
我收到一个错误。
...java: name clash: ... have the same erasure, yet neither overrides the other
有什么办法吗?
到目前为止,我做到了。
public interface TypedTemporalAdjuster<T extends Temporal & Comparable<? super T>> { //extends TemporalAdjuster {
static <T extends Temporal & Comparable<? super T>> TypedTemporalAdjuster<T> of(
final Class<T> temporalClass, final TemporalAdjuster temporalAdjuster) {
return temporal -> temporalClass.cast(temporalAdjuster.adjustInto(temporalClass.cast(temporal)));
}
T adjustInto(T temporal);
}
您不能覆盖具有更严格参数的方法,即 T adjustInto(T temporal);
不会覆盖 Temporal adjustInto(Temporal temporal);
,因为参数类型 T
比 Temporal
更严格。所以你现在有两个名称为 adjustInto
的方法,但是由于类型擦除,参数类型在字节码级别上是相同的,因为 T extends Temporal & Comparable<? super T>
被擦除为 Temporal
.
您可以通过将声明更改为
来解决这个问题public interface TypedTemporalAdjuster<T extends Comparable<? super T> & Temporal>
extends TemporalAdjuster {
T adjustInto(T temporal);
}
那时,语义相同的 T extends Comparable<? super T> & Temporal
被删除为 Comparable
而不是 Temporal
。您还可以使用 T extends Object & Comparable<? super T> & Temporal
,它会被擦除为 Object
(通常,此类知识仅在您需要与 pre-Generics 代码兼容时才有意义)。
然而,根本问题仍然存在,adjustInto(T temporal);
不会覆盖 adjustInto(Temporal temporal);
,因为 T
是一个更具限制性的参数,所以现在,该接口不再是功能接口,因为它有两个抽象方法。
TemporalAdjuster
的子接口必须提供其所有操作,包括接受任何 Temporal
的 adjustInto
。所以你只能做
public interface TypedTemporalAdjuster<T extends Temporal & Comparable<? super T>>
extends TemporalAdjuster {
static <T extends Temporal & Comparable<? super T>> TypedTemporalAdjuster<T> of(
final Class<T> temporalClass, final TemporalAdjuster temporalAdjuster) {
return temporal -> temporalClass.cast(temporalAdjuster.adjustInto(temporal));
}
@Override T adjustInto(Temporal temporal);
}
然而,这种包装调整器不能确保正确的参数,只能隐藏在运行时仍然可能失败的类型转换。但是看起来您正在尝试解决此处不存在的问题,因为您可以简单地在时间上使用 with
方法来获得类型安全的操作,例如
TemporalAdjuster a = TemporalAdjusters.lastDayOfMonth();
LocalDate date1 = LocalDate.now(), date2 = date1.with(a);
LocalDateTime dateTime1 = LocalDateTime.now(), dateTime2 = dateTime1.with(a);
ZonedDateTime zoned1 = ZonedDateTime.now(), zoned2 = zoned1.with(a);
这比你的包装器更强大,就像你做的那样,例如
TemporalAdjuster a = TemporalAdjusters.ofDateAdjuster(date -> date.plusDays(1));
ZonedDateTime zoned1 = ZonedDateTime.now(), zoned2 = zoned1.with(a);
根据 LocalDate
操作,您只需定义一次操作,而它通过即时转换而不是转换来适用于其他时间。