This cant be done because of the concept of Erasure. At runtime both of your 'f()' methods look identical to the compiler and so it will complain you have the same method twice. You have to remember that type parameters are erased at runtime so you have a method that looks like:
public void f(List list);
Therefore you cant invoke f polymorphicaly even this is illegal:
public void f(List<String> list);
public void f(List<Integer> list);
If you have separate method names you can do the following:
public void f(List<? extends A> list);
public void g(List<A> list);
public void h(List<? super B> list);
In method F you could pass any A or subtype of A. G will require a list of A objects only and h will take a list of b or any supertype of B. There is no way to specify sibling classes.
Some references of interest:
http://docs.oracle.com/javase/tutorial/java/generics/lowerBounded.html
http://docs.oracle.com/javase/tutorial/java/generics/upperBounded.html