Diferença para <? super / estende String> no método e declaração de variável

Dado:

import java.util.*;

public class Hancock {
    //insert code here
        list.add("foo");
    }
}

Quais dois fragmentos de código, inseridos independentemente na linha 5, serão compilados sem avisos? (Escolha dois)

A. public void addString(List list) {
B. public void addString(List<String> list) {
C. public void addString(List<? super String> list) {
D. public void addString(List<? extends String> list) {

As respostas corretas são B e C.

As respostas A e B são bastante claras para mim. Para as respostas C & D, eu sei para que lado a herança está indo, no entanto, não consigo entender por que a resposta D não é compilada no Eclipse, enquanto todas as outras fazem (A com aviso sobre genérico, B e C sem guerra).

O erro no Eclipse para a resposta D éThe method add(capture#1-of ? extends String) in the type List<capture#1-of ? extends String> is not applicable for the arguments (String).

Por outro lado, isso compila:

public void addString() {
    List<? extends String> list1 = new ArrayList<String>();
    List<? super String> list2 = new ArrayList<String>();
}

Por quê? Por quê<? super String> não compila na declaração do método enquanto compila na declaração da variável.

Eu sei dissoString é a aula final e não pode ser estendida por nenhuma outra aula, mas isso não me explica o que está acontecendo aqui.

questionAnswers(2)

yourAnswerToTheQuestion