有人可以解释为什么以下不起作用?它抱怨说:
类型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
的类型。
答案 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));
}
}
不确定我是否清楚,希望你明白我的意思!