Java有界类型

时间:2015-07-31 09:48:28

标签: java generics bounded-types

我正在尝试理解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);
}

2 个答案:

答案 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)