又一个Java泛型问题

时间:2011-07-05 14:00:00

标签: java generics

有人可以解释为什么以下不起作用?它抱怨说:

  

类型List中的方法add(C)不适用于参数(Generics.Person)

import java.util.ArrayList;
import java.util.List;

public class Generics<C extends Comparable<C>> {

  static class Person implements Comparable<Person> {
    public final String name, city;

    public Person(String name, String city) {
      this.name = name;
      this.city = city;
    }

    @Override
    public int compareTo(Person that) {
      return 0;
    }
  }

  public Generics() {
    List<C> persons = new ArrayList<C>();
    persons.add(new Person(null, null));
  }

  // however, this one works, but it gives a warning
  // about Comparable being a raw type
  public Generics() {
    List<Comparable> persons = new ArrayList<Comparable>();
    persons.add(new Person(null, null));
  }
}

所以,基本上,我想要的是List的通用Comparables,我可以添加任何实现Comparable的类型。

3 个答案:

答案 0 :(得分:1)

您声明的List<C>C的列表(其中C是您传入的通用类型参数。)您正在尝试添加但是直接Student。这不起作用,因为列表可能不是Student s。

如果您知道列表属于Student个,请将其声明为List<Student>。如果没有,那么您需要将C传递给您的方法,然后直接添加。

答案 1 :(得分:1)

要被允许做你需要做的事,你应该从外面指定Generics类的类型参数:

Generics<Person> generic = new Generics<Person>();

否则,您只是将Person添加到具有未绑定类型变量的列表中,这是不允许的。使用带有自由类型变量的Generics类时,不得对C的类型做任何假设。

要看到明确的例子,请考虑使用第二个class Place extends Comparable<Place>。根据您的尝试,您应该被允许执行以下操作:

public Generics() {
    List<C> persons = new ArrayList<C>();
    persons.add(new Person(null, null));
    persons.add(new Place());
  }

因为Place也是有效的候选人。那么哪个类型变量C?请注意,根据您添加到列表中的内容,没有统一过程试图猜测C的正确类型,最后您应该看到C不是“任何类型,只要它履行约束“但作为”满足约束的指定类型“,

答案 2 :(得分:1)

好的,问题是您正在使用泛型(显然,因为这是编译器所抱怨的)。在你的构造函数中,你说你有一个List,它将接受C类对象。但是,Person不是C类的!或者不一定。假设您创建一个新的泛型实例,如下所示:

Generics<Integer> foo = new Generics<Integer>();

这是合法的,因为Integer确实扩展了可比性。但是,您需要设想这会导致构造函数中的第一行代码“被翻译”为

List<Integer> persons = new ArrayList<Integer>();

显然,您无法将Person对象添加到此列表中;)

以下代码就像魅力一样:

import java.util.ArrayList;
import java.util.List;

public class Generics<C extends Comparable<C>> {

    static class Person implements Comparable<Person> 
    {
        public final String name, city;

        public Person(String name, String city) 
        {
            this.name = name;
            this.city = city;
        }

        @Override
        public int compareTo(Person that) 
        {
            return 0;
        }
    }

    private List<C> _persons = null;

    public Generics() 
    {
        _persons = new ArrayList<C>();
    }

    public void add(C obj)
    {
        _persons.add(obj);
    }

    public static void foo()
    {
        Generics<Person> ppl = new Generics<Person>();
        ppl.add(new Person(null, null));
    }
}

不确定我是否清楚,希望你明白我的意思!