我正在尝试理解Java中的有界类型。我认为我的推理几乎是正确的,但我得到一个错误,我不明白为什么它给了我这个错误,如果A(JsonPerson)是T(Person)的子类。 错误如下(在代码中也有注释):
Error:(22, 16) error: incompatible types: JsonPerson cannot be converted to A
where A is a type-variable:
A extends Person declared in method <A>fromJson(JSONObject)
错误“发生”在返回行中。
我做了一个简单的例子,这是代码
Person.java
public class Person {
private String name;
private String surname1;
private String surname2;
private String phone;
private String email;
public Person(String name, String surname1, String surname2, String phone, String email) {
this.name = name;
this.surname1 = surname1;
this.surname2 = surname2;
this.phone = phone;
this.email = email;
}
public String getName() {
return name;
}
public String getSurname1() {
return surname1;
}
public String getSurname2() {
return surname2;
}
public String getPhone() {
return phone;
}
public String getEmail() {
return email;
}
}
JsonPerson.Java
public class JsonPerson extends Person implements JSONSerializableInterface<Person> {
public JsonPerson(String name, String surname1, String surname2, String phone, String email) {
super(name, surname1, surname2, phone, email);
}
/**
* Error:(22, 16) error: incompatible types: JsonPerson cannot be converted to A
* where A is a type-variable:
* A extends Person declared in method <A>fromJson(JSONObject)
* */
@Override
public <A extends Person> A fromJson(JSONObject json) throws JSONException {
String name = json.getString("name");
String surname1 = json.getString("surname1");
String surname2 = json.getString("surname2");
String phone = json.getString("phone");
String email = json.getString("email");
return new JsonPerson(name, surname1, surname2, phone, email);
}
@Override
public JSONObject toJson(Person object) {
return null;
}
}
JSONSerializableInterdace.java
public interface JSONSerializableInterface<T> {
public <A extends T> A fromJson(JSONObject json) throws JSONException;
public JSONObject toJson(T object);
}
答案 0 :(得分:4)
问题是有人可能会这样称呼你的方法:
new JSONPerson().fromJSON<SpecialPerson>(json);
其中SpecialPerson
扩展Person
。这是有效的(因为A
扩展了Person
),但该方法返回的JSONPerson
不是SpecialPerson
。
答案 1 :(得分:3)
像
这样的签名public <A extends T> A fromJson(JSONObject json)
真的没有多大意义。这表示返回的对象类型由调用者决定。呼叫者可以提供类型证人,例如<CleverPerson>
方法,并期望返回CleverPerson
,但除非将类型显式传递给方法,否则无法工作(否则类型A
甚至不可用在运行时)。这样的事情会有意义:
public <A extends T> A fromJson(Class<A> clazz, JSONObject json)
但是,我认为最好是这样做:
public T fromJson(JSONObject json)