W jaki sposób JLS określa, że ​​symboli wieloznacznych nie można formalnie używać w metodach?

Zawsze zastanawiałem się nad jakimś dziwnym aspektem generics Java i używaniem symboli wieloznacznych. Powiedzmy, że mam następujący interfejs API:

public interface X<E> {
    E get();
    E set(E e);
}

A następnie, powiedzmy, deklarujemy następujące metody:

public class Foo {
    public void foo(X<?> x) {
        // This does not compile:
        x.set(x.get());
    }

    public <T> void bar(X<T> x) {
        // This compiles:
        x.set(x.get());
    }
}

Z mojego „intuicyjnego” zrozumieniaX<?>&nbsp;jest w rzeczywistości taki sam jakX<T>, z wyjątkiem tego, co nieznane<T>&nbsp;jestformalnie&nbsp;nieznany kodowi klienta. Ale w środkufoo(), Zgaduję, że kompilator może wywnioskować (pseudo kod JLS)<T0> := <?>[0], <T1> := <?>[1], etc.... To właśnie robi większość programistów w sposób jawny i intuicyjny. Przekazują prywatną metodę pomocniczą, co prowadzi do wielu niepotrzebnych kodów płyt kotłowych:

public class Foo {
    public void foo(X<?> x) {
        foo0(x);
    }

    private <T> void foo0(X<T> x) {
        x.set(x.get());
    }
}

Inny przykład:

public class Foo {
    public void foo() {
        // Assuming I could instanciate X
        X<?> x = new X<Object>();
        // Here, I cannot simply add a generic type to foo():
        // I have no choice but to introduce a useless foo0() helper method
        x.set(x.get());
    }
}

Innymi słowy, kompilator wie, że znak wieloznaczny jest wx.set()&nbsp;jest formalnie taki sam jak znak wieloznacznyx.get(). Dlaczego nie może wykorzystać tych informacji? Czy istnieje aspekt formalny wJLS, to wyjaśnia tę brakującą kompilator „funkcję”?