java - 使用泛型作为返回类型参数 Java
问题描述
我正在尝试创建一个返回泛型类型参数的方法。
我有一个扩展抽象类 Order 的类 VehicleOrder。在 Order 类中,我创建了一个抽象方法 receiveHiredObject。此方法不会接收任何参数,并将返回一个泛型。
public abstract class Order implements Orderable {
private Date date;
private Customer customer;
public abstract <T> T receiveHiredObject();
我在类 VehicleOrder 中实现了这个方法,并将它设置为返回类参数车辆。
public class VehicleOrder extends Order {
private Vehicle vehicle;
public VehicleOrder(final Date date, final Customer customer, final Vehicle vehicle) {
super(date, customer);
this.vehicle = vehicle;
}
@SuppressWarnings("unchecked")
@Override
public Vehicle receiveHiredObject() {
return vehicle;
}
问题是,当我实例化一个 Order 类型的新 VehilceOrder 并且使用方法 receiveHiredObject 时,此方法返回给我一个对象,而我只有方法 toString 可用。
Order a = new VehicleOrder();
a.receiveHiredObject();
我希望将来对其他类型的对象(如 HotelOrder)使用相同的方法。
我做错了什么,为什么方法 receiveHiredObject 返回一个 Object 而不是 VehicleOrder?如何改进返回正确类型的方法?
谢谢,
解决方案
请注意receiveHiredObject
,如果您告诉它要返回什么类型,则“返回正确的类型”。
Order order = new VehicleOrder();
Vehicle v = order.receiveHiredObject();
它返回Object
是因为在没有您指定类型的情况下,类型参数T
会被推断为Object
,因为T
仅以 为界Object
。
但是,您的方法根本不安全!你可以做一些愚蠢的事情,比如:
Order order = new VehicleOrder();
Hotel h = order.receiveHiredObject();
这将编译,但当你运行它时会崩溃。
这是因为您声明receiveHiredObject
返回一个T
- 泛型参数。这意味着T
调用者指定的任何内容 - 无论是Vehicle
、Hotel
还是Foo
,receiveHiredObject
都被声明为返回该类型的事物。显然,它不会那样做。它返回的内容取决于使用的子类。调用者无法决定它返回什么!当您实现receiveHiredObject
in 时VehicleOrder
,您会收到警告,因为返回的 aVehicle
可能不是T
调用者所期望的,并且运行时无法为您检查,但您抑制了警告。
所以receiveHiredObject
根本不应该是通用的。您可以改为Order
通用:
// might have to change Orderable too, if receiveHiredObject comes from there
public abstract class Order<T> implements Orderable {
private Date date;
private Customer customer;
public abstract T receiveHiredObject();
}
public class VehicleOrder extends Order<Vehicle> {
// same code as before...
}
现在调用者可以这样做:
Order<Vehicle> order = new VehicleOrder();
order.receiveHiredObject().someVehicleSpecificThing();
现在它更安全了——您将无法从车辆订单中获得酒店。
请注意,绝对有必要提供 的类型信息Vehicle
。这是因为order.receiveHiredObject
返回的内容是由 的运行时类型决定的order
,编译器无法知道它是什么。在极端情况下思考:
Order order = new Random().nextBoolean() ? new VehicleOrder() : new HotelOrder();
// what type should order.receiveHiredObject return here?
推荐阅读
- python - 试图弄清楚为什么 BS 返回一个空列表
- spring-boot - 为 Spring Boot 应用程序创建具有命名/主机卷的 Docker 映像
- python - 在 df 中的列列表中运行 for 循环
- node.js - NextJS 在滚动时延迟加载 div 列表
- c++ - 为什么 C++ 流将布尔值视为数字?
- django - 同一视图中的 Django 多表单处理
- python - 尝试替换文本但字符串未更改
- javascript - React 组件正在重新渲染从状态中删除的项目
- reactjs - 接口命名约定(接口名称与组件名称冲突)
- react-router-dom - 右键单击以在新选项卡中打开 React Link 抛出 404 Not Found 错误