不能 return 从泛型方法对象

Cannot return object from generic method

我不明白为什么以下代码无法编译。我已经声明了扩展 Customer 的泛型类型 TCustomerCustomer 类型,所以为什么我不能 return Customer 对象从这个方法没有强制转换?

public class CustomerExample {

    public <T extends Customer> T processCustomer(Customer customer) {
        return new Customer();
    }
}

class Customer {

}

我得到java: incompatible types: Customer cannot be converted to T

您需要显式转换:

public <T extends Customer> T processCustomer(Customer customer) {
    return (T) new Customer();
}

当然,您需要注意运行时的这种类型转换,因为您不能这样做:

class Client extends Customer {
}

这样,以下调用将在运行时失败并出现 class 转换异常:

Client client = new CustomerExample().processCustomer(new Client());

那是因为运行时 classes 不匹配。这只是意味着您的 processCustomer 实现必须有效地通用(无论如何都不能绑定到一种静态类型)

假设您调用了您的方法:

Customer customer = ...
SomeCustomerSubClass c = processCustomer(customer);

在那种情况下,编译器期望 processCustomer 到 return 一个 SomeCustomerSubClass,所以它不允许你的 processCustomer 到 return 一个 Customer.

如果您正在 return 创建一个 Customer 实例,您应该问自己为什么首先要使用泛型类型参数。

请记住,作为方法的作者,您无法决定方法的通用参数是什么。你不能断言 T 一定是 Customer。来电者可以。

在您的例子中,您将 T 限制为 CustomerCustomer 本身的子类。然而你 return 是 Customer 的实例。如果调用者将 T 指定为 AngryCustomerCustomer 的子类),则会产生矛盾。来电者希望您 return 一个 AngryCustomer 但您 return 一个 Customer!

要解决此问题,您可以将 extends 更改为 super,以便 T 可以是 CustomerCustomer 本身的任何超类。现在一切都说得通了。如果调用者指定TObject,则Customer类型兼容Object,但不兼容AngryCustomer

或者,根本不要使用泛型。您当前对该方法的实现似乎不适合通用。

T 扩展了 CustomerCustomer 没有扩展 T

在您的实际代码中:

public <T extends Customer> T processCustomer(Customer customer) {
    return new Customer();
}

你 return 一个超级 class 实例 (Customer) 在声明为 returned 的方法中键入它的子class (T).
没有向下转型是无效的,因为将超级 class 变量分配给子 class 变量是无效的,例如 :

T t = customer;

你应该写:

T t = (T)customer;  

因此您还需要在此处转换为 T :

public <T extends Customer> T processCustomer(Customer customer) {
    return (T) new Customer();
}

很简单,客户不执行T

例如让我们像这样创建 T:

class T extends Customer {
    int i;
    public T(int i) {
        this.i = i;
    }
}

您想如何使用 Customer 创建 T?不可能。