Java中使用泛型定义方法返回值时调用返回Object类型问题求解
问题本质原因
你当前的泛型参数定义在了方法层级,而非类层级,方法级泛型的实际类型需要在每次方法调用时确定,和当前类的子类类型没有绑定关系。当你使用无泛型的Order父类引用调用receiveHiredObject()时,编译器没有足够的上下文推断泛型T的实际类型,就会使用泛型的上界,你定义的<T>没有指定上界,默认上界为Object,因此返回值类型就是Object。
另外你子类实现中的@SuppressWarnings("unchecked")是完全多余的,这里你只是用到了Java方法重写的协变返回特性(子类重写方法可以返回父类方法返回值的子类),和泛型实现没有关联,这个注解反而掩盖了泛型定义错误的问题。
核心错误点
- 泛型参数定义位置错误:本需要和Order子类绑定的返回类型泛型,被错误定义为方法级泛型,无法和子类的具体返回类型关联
- 父类调用时无类型推断依据:方法级泛型需要调用时显式指定类型,或有赋值上下文辅助推断,直接调用无上下文的情况下会被擦除为上界
Object - 子类实现未和父类泛型绑定:子类重写的返回值仅为协变返回,父类完全感知不到子类的实际返回类型
优化方案
将泛型参数定义移到抽象类层级,每个子类继承时指定对应返回类型的泛型参数即可完美适配多子类场景:
1. 修改抽象父类Order定义
// 类级别声明泛型T,代表当前Order子类对应的租用对象类型 public abstract class Order<T> implements Orderable { private Date date; private Customer customer; // 补充父类构造方法 public Order(Date date, Customer customer) { this.date = date; this.customer = customer; } // 方法直接返回类级别泛型T,无需再在方法上声明泛型 public abstract T receiveHiredObject(); }
2. 修改VehicleOrder实现
// 继承Order时指定泛型参数为Vehicle,无需再加多余的抑制警告注解 public class VehicleOrder extends Order<Vehicle> { private Vehicle vehicle; public VehicleOrder(final Date date, final Customer customer, final Vehicle vehicle) { super(date, customer); this.vehicle = vehicle; } @Override public Vehicle receiveHiredObject() { return vehicle; } }
3. 拓展其他Order子类示例(以HotelOrder为例)
public class HotelOrder extends Order<Hotel> { private Hotel hotel; public HotelOrder(final Date date, final Customer customer, final Hotel hotel) { super(date, customer); this.hotel = hotel; } @Override public Hotel receiveHiredObject() { return hotel; } }
4. 正确调用示例
// 声明引用时指定泛型类型,调用方法直接返回对应类型,无需强转 Order<Vehicle> vehicleOrder = new VehicleOrder(/*构造参数*/); Vehicle vehicle = vehicleOrder.receiveHiredObject(); Order<Hotel> hotelOrder = new HotelOrder(/*构造参数*/); Hotel hotel = hotelOrder.receiveHiredObject();
内容的提问来源于stack exchange,提问作者Alin Balan
相关产品推荐
相关产品推荐

