为了账号安全,请及时绑定邮箱和手机立即绑定

如何将非通用接口扩展为通用接口?

如何将非通用接口扩展为通用接口?

UYOU 2021-08-19 21:38:28
我试图扩展,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:名称冲突:...具有相同的擦除,但都不覆盖另一个有没有办法做到这一点?到目前为止,我做到了。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);}
查看完整描述

1 回答

?
神不在的星期二

TA贡献1963条经验 获得超6个赞

您不能覆盖具有更多限制参数的方法,即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> & Temporalwhich 被擦除Object(通常,此类知识仅在您需要与 pre-Generics 代码兼容时才相关)。


但是,根本问题仍然存在,adjustInto(T temporal);不会覆盖adjustInto(Temporal temporal);作为T更具限制性的参数,因此现在接口不再是功能接口,因为它有两个抽象方法。


的子接口TemporalAdjuster必须提供其所有操作,包括adjustInto接受 any 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);

}

然而,这种包装的调整器不能确保正确的参数,只能隐藏在运行时仍然可能失败的类型转换。但看起来您正在尝试解决一个不存在的问题,因为您可以简单地使用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操作,而它通过即时转换而不是强制转换来适用于其他时间。


查看完整回答
反对 回复 2021-08-19
  • 1 回答
  • 0 关注
  • 141 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信