public  void takeList(List<? extends String> list){
        list.add("foo"); 
    }

解决方案 »

  1.   


    public  void takeList(List<String> list){
            list.add("foo"); 
        }
    这样不行么?
      

  2.   

    public  void takeList(List<? extends String> list){
            list.add("foo"); 
        }
    list是一个带上线通配符泛型参数的List,然后调用add,add的参数就是“? extends String”,编译器并不能理解这个时候需要那个String的子类型,因此就不会接受任何类型的参数,所以报错。
      

  3.   

    改成这样就不会报错了
    public  void takeList(List<? super String> list){
            list.add("foo"); 
        }
    但是此时调用返回类型带泛型参数的方法是,编译器就会报错,比如get()
      

  4.   

    ?extends XX 是上限是XX
    就是说?是XX的子类
      

  5.   

    String是final类型,怎么会被继承呢???
      

  6.   

    改成Object为什么也不行,字符串难道不是Object的子类? public  void takeList(List<? extends Object> list){
            list.add("foo");
        }
      

  7.   

    改成什么都不行,上限通配符“? extends Object”只是限定它是一种Object的子类型,至于那种类型,编译器是不知道的,所以不能在形参列表中带有泛型参数的方法中使用那个“?”类型,编译器没那么聪明,他不认识这个“?”
      

  8.   

    这样写还不如这样写
    list<String>
    反正list<? extends String>也是string不过String是final的哦
      

  9.   

    哎,看你们在JAVA中有如此造诣了,我太惭愧,路过,呵呵
      

  10.   

    对啊,String是Object的子类型啊。按照书上的讲法是应该可以的,? super String就可以证明。《core java》有个例子,如下:
    import java.util.*;/**
     * @version 1.00 2004-05-10
     * @author Cay Horstmann
     */
    public class PairTest3
    {
       public static void main(String[] args)
       {
          Manager ceo = new Manager("Gus Greedy", 800000, 2003, 12, 15);
          Manager cfo = new Manager("Sid Sneaky", 600000, 2003, 12, 15);
          Pair<Manager> buddies = new Pair<Manager>(ceo, cfo);      
          printBuddies(buddies);      ceo.setBonus(1000000);
          cfo.setBonus(500000);
          Manager[] managers = { ceo, cfo };      Pair<Employee> result = new Pair<Employee>();
          minmaxBonus(managers, result);
          System.out.println("first: " + result.getFirst().getName() 
             + ", second: " + result.getSecond().getName());
          maxminBonus(managers, result);
          System.out.println("first: " + result.getFirst().getName() 
             + ", second: " + result.getSecond().getName());
       }   public static void printBuddies(Pair<? extends Employee> p)//请看这里。
       {
          Employee first = p.getFirst();
          Employee second = p.getSecond();
          System.out.println(first.getName() + " and " + second.getName() + " are buddies.");
       }   public static void minmaxBonus(Manager[] a, Pair<? super Manager> result)
       {
          if (a == null || a.length == 0) return;
          Manager min = a[0];
          Manager max = a[0];
          for (int i = 1; i < a.length; i++)
          {
             if (min.getBonus() > a[i].getBonus()) min = a[i];
             if (max.getBonus() < a[i].getBonus()) max = a[i];
          }
          result.setFirst(min);
          result.setSecond(max);
       }   public static void maxminBonus(Manager[] a, Pair<? super Manager> result)
       {
          minmaxBonus(a, result);
          PairAlg.swapHelper(result); // OK--swapHelper captures wildcard type
       }
    }class PairAlg
    {
       public static boolean hasNulls(Pair<?> p)
       {
          return p.getFirst() == null || p.getSecond() == null;
       }   public static void swap(Pair<?> p) { swapHelper(p); }   public static <T> void swapHelper(Pair<T> p)
       {
          T t = p.getFirst();
          p.setFirst(p.getSecond());
          p.setSecond(t);
       }
    }class Employee
    {  
       public Employee(String n, double s, int year, int month, int day)
       {  
          name = n;
          salary = s;
          GregorianCalendar calendar = new GregorianCalendar(year, month - 1, day);
          hireDay = calendar.getTime();
       }   public String getName()
       {
          return name;
       }   public double getSalary()
       {  
          return salary;
       }   public Date getHireDay()
       {  
          return hireDay;
       }   public void raiseSalary(double byPercent)
       {  
          double raise = salary * byPercent / 100;
          salary += raise;
       }   private String name;
       private double salary;
       private Date hireDay;
    }class Manager extends Employee
    {  
       /**
          @param n the employee's name
          @param s the salary
          @param year the hire year
          @param month the hire month
          @param day the hire day
       */
       public Manager(String n, double s, int year, int month, int day)
       {  
          super(n, s, year, month, day);
          bonus = 0;
       }   public double getSalary()
       { 
          double baseSalary = super.getSalary();
          return baseSalary + bonus;
       }   public void setBonus(double b)
       {  
          bonus = b;
       }   public double getBonus()
       {  
          return bonus;
       }   private double bonus;
    }
      

  11.   

    /**
     * @version 1.00 2004-05-10
     * @author Cay Horstmann
     */
    public class Pair<T> 
    {
       public Pair() { first = null; second = null; }
       public Pair(T first, T second) { this.first = first;  this.second = second; }   public T getFirst() { return first; }
       public T getSecond() { return second; }   public void setFirst(T newValue) { first = newValue; }
       public void setSecond(T newValue) { second = newValue; }   private T first;
       private T second;
    }
      

  12.   

    public static void printBuddies(Pair<? extends Employee> p)//请看这里。
       {
          Employee first = p.getFirst();
          Employee second = p.getSecond();
          System.out.println(first.getName() + " and " + second.getName() + " are buddies.");
       }p调用的方法public T getSecond() { return second; }的形参列表中不含泛型参数吧
    public static void maxminBonus(Manager[] a, Pair<? super Manager> result)
       {
          minmaxBonus(a, result);
          PairAlg.swapHelper(result); // OK--swapHelper captures wildcard type
       }这个事下限通配符,super的,它调用的方法的返回值不含泛型参数吧综上所述,完全和我说的一样啊
      

  13.   

    那LS能不能解释一篇讲? extends 和?super的文章看看,我看到的例子都是用来取某些东西,而不会对参数进行一些修改,如list.add这种操作。不是很明白。
      

  14.   

    这个写法是不是可以改成
    public <T extends String> void takeList(List<T> list){
      list.add("foo");
    }
    这里同样出错,但是这样看起来更明显一些。list.add(T);才是正确的。“foo”是String,但是不代表只有这一种String.虽然String是final的。但是去掉这个特殊性,这种用法很显然是不对的。不能用parent的对象代替child对象。
      

  15.   

    那么,为什么? super String的时候,就对了?
      

  16.   

    super和extends是取值相反的两个关键字,可以用child代表parent. String就是这个集合中的child.
      

  17.   

    LZ请看下面的:
    Collection<?> c = new ArrayList<Integer>();
    c.add(new Integer(1)); // 编译错误
    因为这个“?”代表的是未知类型,不能将任何类型的对象添加到其中,但是可以从未知类型的集合中取出元素:
    List<Integer> l = new ArrayList<Integer>();
    l.add(new Integer(1));
    List<?> l2 = l;
    Object o = l2.get(0);
    System.out.println(o);
    使用“?”时,也可以限定条件:
    static void f(Collection<? extends Number> c) {
    for (Number number : c) {
    System.out.println(number);
    }
    }
    这时f方法只能接受元素类型是Number或其子类的属于Collection的泛型集合参数查看Collections.copy(dest, src);方法时会发现:
    public static <T> void copy(List<? super T> dest, List<? extends T> src){}
    这里的"? super T"表示的是这个未知类型“?”必须是T或者它的父类在泛型中有个比较重要的一点:
    如果A是B的子类,T是一个泛型类(或接口),那么G<A>并不是G<B>的子类型希望这些能对你有用
      

  18.   

    谢谢,有用,是否能讲讲? super String的时候,为什么List.add("foo")没问题,这个时候类型也是未知的呀。