Intuitively, your code makes sense; however, a restriction in a system such as Java makes it illegal. First, consider a simpler example.
<T> void f1(List<T> a){ ... } <T> void f2(List<T> a1, List<T> a2){ ... } List<?> a = ...; f1(a);
When compiling f1(a) compiler internally considers type a as List<X> , where X is a fixed, albeit unknown type. This is called a wildcard. By passing the compilation List<X> to f1 , the compiler reports that T = X.
When compiling f2(a,a) , this happens; however, group capture is applied to two occurrences of a separately, as a result, the first a is of type List<X1> , and the second a of type List<X2> . The compiler does not analyze that a remains unchanged, therefore X1=X2 . Without this knowledge, passing List<X1> and List<X2> to f2() will not compile.
The workaround is to do a only once:
List<?> a = ...; f2_1(a);
Back to your case, you also need a helper method:
<T, U> Form<U> createForm(Component<T, U> component, T object, String prefix) { return component.createForm(component.get(object), prefix + subPrefix); } -- Component<T, ?> component = e.getValue(); Form<?> form = createForm(component, object, prefix + subPrefix);
For the next problem you will need a throw. Another way to tell the compiler is that the component and the form have the same U This relationship cannot be expressed in a system like Java, but it is guaranteed by your code logic. You can legitimately suppress a warning because you have "checked" to make sure that the cast should work at run time.