Jin*_*won 4 java generics java-8 functional-interface
我试图扩展,TemporalAdjuster以便看起来像,
public interface TypedTemporalAdjuster<T extends Temporal & Comparable<? super T>> {
T adjustInto(T temporal);
}
Run Code Online (Sandbox Code Playgroud)
当我试图直接扩展基接口时,
public interface TypedTemporalAdjuster<T extends Temporal & Comparable<? super T>>
extends TemporalAdjuster {
T adjustInto(T temporal);
}
Run Code Online (Sandbox Code Playgroud)
我收到了一个错误.
... java:name clash:...有相同的擦除,但都没有覆盖另一个
有没有办法做到这一点?
到目前为止,我做到了.
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);
}
Run Code Online (Sandbox Code Playgroud)
您不能覆盖具有更多限制性参数的方法,即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);
}
Run Code Online (Sandbox Code Playgroud)
然后,语义上相同的T extends Comparable<? super T> & Temporal被删除Comparable而不是Temporal.您也可以使用T extends Object & Comparable<? super T> & Temporal哪些被删除Object(通常,只有当您需要与前Generics代码兼容时,此类知识才有用).
然而,根本的问题仍然存在,adjustInto(T temporal);不会覆盖adjustInto(Temporal temporal);的T是更严格的参数,所以现在,接口不是一个功能接口了,因为它有两个抽象方法.
TemporalAdjuster必须提供其所有操作的子接口,包括adjustInto接受任何操作Temporal.所以你只能这样做
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);
}
Run Code Online (Sandbox Code Playgroud)
但是,这样的包装调整器无法确保正确的参数,只能隐藏仍然可能在运行时失败的类型转换.但是看起来你正试图在这里解决一个不存在的问题,因为你可以简单地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);
Run Code Online (Sandbox Code Playgroud)
这比你的包装更强大,就像你做的那样,例如
TemporalAdjuster a = TemporalAdjusters.ofDateAdjuster(date -> date.plusDays(1));
ZonedDateTime zoned1 = ZonedDateTime.now(), zoned2 = zoned1.with(a);
Run Code Online (Sandbox Code Playgroud)
您定义的操作只有一次,在方面LocalDate操作,同时通过将它们即时的,而不是铸造适用于其他temporals.