如何将类型参数的值绑定到“this”的类型?

How to bind value of type parameter to type of `this`?

interface A<T extends B</*?*/>> {
    method(T param);
}

interface B<U extends A> {
    // ...
}

在上面的代码片段中,如何表达方法 A#method 应该只接受按调用该方法的类型(或其后代)参数化的对象的参数。

我想实现这样的目标:

interface Vehicle<T extends SteeringDevice</*?*/> {
    default steer(T steeringDevice) {
        // ...
    }
}

interface SteeringDevice<U extends Vehicle> {
    // ...
}

// -----

class Car implements Vehicle<SeeringWheel> {
    // ...
}

class SteeringWheel implements SteeringDevice<Car> {
    // ...
}

// -----

class Bike implements Vehicle<Handlebars> {
    // ...
}

class Handlebars implements SteeringDevice<Bike> {
    // ...
}

... 可以安全地调用 new Car().steer(new SteeringWheel()) 而不是 new Car().steer(new Handlebars()).

我认为这符合您的要求:

interface Vehicle<T extends SteeringDevice<? extends Vehicle<T>>> {
    default void steer(T steeringDevice) {}
}

interface SteeringDevice<U extends Vehicle<? extends SteeringDevice<U>>> {
    // ...
}

这迫使两个兼容的实现相互cross-reference。将参数更改为不兼容的类型现在将在配对的 class.

中触发编译错误

上面的一个潜在问题是它允许 SteeringDevice<Car> 的多个实现。您可以通过添加自我类型参数使配对更加明确:

interface Vehicle<U extends Vehicle<U, T>, T extends SteeringDevice<T, U>> {
    default void steer(T steeringDevice) {}
}

interface SteeringDevice<T extends SteeringDevice<T, U>, U extends Vehicle<U, T>> {
    // ...
}

class Car implements Vehicle<Car, SteeringWheel> {
    // ...
}

class SteeringWheel implements SteeringDevice<SteeringWheel, Car> {
    // ...
}

仍然可以创建另一个 SteeringDevice<SteeringWheel, Car> 的实现,因为 Java 没有真正的自我类型,但至少它使违规更明显。它还具有在无效类型参数上破坏 both classes 的优点。