gpt4 book ai didi

java - 自类型 - 需要类型绑定(bind)内的类型

转载 作者:行者123 更新时间:2023-12-03 10:03:37 25 4
gpt4 key购买 nike

我想知道是否可以限制在接口(interface)上声明的方法要求类型绑定(bind)内的类型。实际上,我想提供一种在无法提供真正类型安全的情况下强制转换类型安全的方法。
例如,考虑具有基类型 Base 的层次结构。它是通过中间接口(interface)继承的。通常,人们知道接口(interface) FirstInterface 的类型。但不是什么特定的类正在实现它。我想要一种方法,它允许转换为接口(interface)的任一实现,而不允许转换为 Base 的其他实现。如以下示例所示:

interface Base<TYPE extends Base<TYPE>> {
default <CAST extends TYPE> CAST as(Class<? extends CAST> type) {
if (type.isInstance(this)) {
return type.cast(this);
} else {
throw new IllegalArgumentException();
}
}
}

interface FirstIface<TYPE extends FirstIface<TYPE>> extends Base<TYPE> { }
class FirstClassA implements FirstIface<FirstClassA> { }
class FirstClassB implements FirstIface<FirstClassB> { }

interface SecondIface<TYPE extends SecondIface<TYPE>> extends Base<TYPE> { }
class SecondClassA implements SecondIface<SecondClassA> { }
class SecondClassB implements SecondIface<SecondClassB> { }

interface ThirdIface<TYPE extends ThirdIface<TYPE>> extends FirstIface<TYPE>, SecondIface<TYPE> { }
class ThirdClassA implements ThirdIface<ThirdClassA> { }
class ThirdClassB implements ThirdIface<ThirdClassB> { }
我希望能够在 Java 中编译以下代码:
FirstIface<?> i = new FirstClassA();
FirstClassA a = i.as(FirstClassA.class); // desired: compiles, now: compiler error
FirstClassB b = i.as(FirstClassB.class); // desired: runtime exception, now: compiler error
这同样适用于 ThirdIFace 的层次结构。 ,而以下代码应呈现编译器错误:
SecondIface<?> i = new SecondClassA();
SecondClassA a = i.as(SecondClassA.class); // now and desired: compiler error
SecondClassB b = i.as(SecondClassB.class); // now and desired: compiler error
有什么方法可以声明 Base.as保留这个要求?代码是自动生成的,因此也可以在自动生成的接口(interface)中提供覆盖(就像类一样)。使用覆盖时, SecondIface extends FirstIface 的场景.

最佳答案

如果您的目标是只允许可能成功的调用,则可能成功意味着我们(静态地)知道 SUBSUPER 的子类型当试图转换类型为 SUPER 的实例时输入 SUB ,我不确定这是否可能。
一个问题,即使在克服了没有类型变量的问题之后,比如说,中间自我类型(在你的例子中是 FirstIface<?>),编译器会推断出 SUPER==Object。 (或 SUPER==Base<?> )如果需要满足 SUB extends SUPER .

The code is auto-generated, so it would also be possible to provide an override in the interfaces which are auto-generated


我认为这不会有帮助。目标是让子接口(interface)中的方法具有比父类(super class)型中声明的更严格的参数类型,但参数类型不是协变的(协变参数类型会违反 Liskov 替换原则)

But since the wildcard could be any subtype of FirstIface, it does not allow for any subtype of FirstIFace


是的。我们只有 1) self 类型变量 TYPE用于最终实现类型,以及 2) Base 的类型界面。我们没有办法记下调用站点已知的中间类型信息的类型。
我怀疑最接近您的目标的是:
  • 对类型转换使用静态方法,
  • 避免在调用点使用类型推断,因为 javac 会很乐意推断 Object让父类(super class)型编译代码。

  • 当然,这不是一个好的解决方案,因为避免类型推断是不切实际的。这是一个完整的例子:
    public class Hello {
    interface Base<TYPE extends Base<TYPE>> {}

    interface FirstIface<TYPE extends FirstIface<TYPE>> extends Base<TYPE> {}

    static final class FirstClassA implements FirstIface<FirstClassA> { }
    static final class FirstClassB implements FirstIface<FirstClassB> { }

    interface SecondIface<TYPE extends SecondIface<TYPE>> extends Base<TYPE> { }

    static final class SecondClassA implements SecondIface<SecondClassA> { }
    static final class SecondClassB implements SecondIface<SecondClassB> { }

    public static void main(String[] args) {
    FirstIface<?> i = new FirstClassA();

    FirstClassA a = Hello.<FirstIface<?>, FirstClassA>as(i, FirstClassA.class); // works
    FirstClassB b = Hello.<FirstIface<?>, FirstClassB>as(i, FirstClassB.class); // runtime error

    SecondClassA c = Hello.<FirstIface<?>, SecondClassA>as(i, SecondClassA.class); // compile error
    SecondClassB d = Hello.<FirstIface<?>, SecondClassB>as(i, SecondClassB.class); // compile error
    }

    static <SUPER, SUB extends SUPER> SUB as(SUPER obj, Class<? extends SUB> c) {
    return (SUB) obj;
    }
    }

    关于java - 自类型 - 需要类型绑定(bind)内的类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64259947/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com