ジェネリックスのワイルドカードとキャスト

S2JUnit4の拡張アサートの「データセットとマップのリストが等しいことをアサート」するメソッド

public static void assertMapEquals(String message, DataSet expected,
        List<Map<?, ?>> list) {
    adapter.assertMapListEquals(message, expected, list);
}

を使いたかったのですが、なぜか「データセットとマップが等しいことをアサート」するメソッド

public static void assertMapEquals(String message, DataSet expected,
        Map<?, ?> map) {
    adapter.assertMapEquals(message, expected, map);
}

の方を呼びにいこうとしてしまい、パラメータの型が一致しないとコンパイラに怒られてしまって困ってしまいました。
原因はパラメータとしてList>型を渡していたことだったのですが、これが分からず結構ハマってしまいました。要はジェネリックスについての理解が足りなかったようです。

List<?> list1 = new ArrayList<String>();
List<?> list2 = new ArrayList<?>();
List<Map<?, ?>> list3 = new ArrayList<Map<String, Object>>();
List<Map<?, ?>> list4 = new ArrayList<Map<?, ?>>();

list1とlist3が○でlist2とlist4が×だと勘違いしていたのですが、実際にはlist1とlist4が○でlist2とlist3が×でした。よくよく考えれば確かに納得なのですが。。。