I will again rename your classes, so that everything is more readable. So, let's have:
public class First<T extends Second, U extends First<T, U>> {
Third<T, U> c;
void test() {
c.acceptParameterOfTypeA(this);
}
}
class Second {
}
public class Third<X extends Second, Y extends First<X, Y>> {
void acceptParameterOfTypeA(Y a) {
}
}
From the definition of the c member (Third<T, U>), we can conclude that c will expose a method with this signature:
void acceptParameterOfTypeA(U a) { .. }
What is U? U is a sub-type of First<T, U>.
But if U can be substituted with First after type-erasure, this will mean that First extends First<T, First>, which is not true, because U stands for sub-type of First, which is parameterized with some concrete sub-types of Second and First.
In order to get to U, you can apply the so-called Get This approach.
First, since you need U, which is a sub-type of First, but can't get it from First, you can introduce an abstract method that returns it:
abstract class First<T extends Second, U extends First<T, U>> {
Third<T, U> c;
void test() {
c.acceptParameterOfTypeA(getU());
}
abstract U getU();
}
Then, implement a sample sub-class of First, called Fourth, which extends First with some concrete types for T and U, for example:
class Fourth extends First<Second, Fourth> {
Fourth getU() {
return this;
}
}
In the getU() method, just do return this; as this will return the correct substitute for U in the super-class.
More info: