当前位置: 首页 > 知识库问答 >
问题:

使用泛型返回类型参数Java

刘德义
2023-03-14

我试图创建一个返回泛型类型参数的方法。

我有一个类车辆订单扩展抽象类订单。在类订单中,我创建了一个抽象方法接收HiredObject。这个方法不会接收任何参数,并将返回一个泛型。

public abstract class Order implements Orderable {

private Date date;
private Customer customer;

public abstract <T> T receiveHiredObject();

我在VehicleOrder类中实现了这个方法,并将其设置为返回类参数vehicle。

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;
}

问题是,当我实例化一个新的VeilceOrderorororororororororororororderorororororororforhiredObject时,这个方法返回给我一个Object,而我只有方法toString可用。

Order a = new VehicleOrder();
a.receiveHiredObject();

我希望将来对HotelOrder等其他类型的对象使用相同的方法。

我做错了什么,为什么receiveHiredObject方法返回的是一个对象而不是VehicleOrder?如何改进方法以返回正确的类型?

谢谢你,

共有2个答案

松正阳
2023-03-14

您可以将泛型类型声明移动到类级别,例如:

public abstract class Order<T> implements Orderable {
    private Date date;
    private Customer customer;

    public abstract T receiveHiredObject();
}

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;
    }

    @SuppressWarnings("unchecked")
    @Override
    public Vehicle receiveHiredObject() {
         return vehicle;
    }
}

(认为语法正确)

轩辕修能
2023-03-14

请注意,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——无论是VehicleHotel,还是FooreceiveHiredObject都会声明返回该类型的对象。显然,它不会这样做。它返回的内容取决于使用的子类。来电者无法决定返回的内容!当您在VehicleOrder中实现receiveHiredObject时,您会收到一条警告,因为返回Vehicle可能不是调用者期望的T,运行时无法为您检查,但您抑制了该警告。

因此,receiveHiredObject不应该是泛型的。您可以改为使订单通用:

// 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();

现在它安全多了——你将无法通过汽车订单获得酒店。

请注意,绝对有必要提供车辆的类型信息。这是因为什么顺序。receiveHiredObject返回值由运行时类型的顺序决定,编译器无法知道这是什么。在极端情况下想想:

Order order = new Random().nextBoolean() ? new VehicleOrder() : new HotelOrder();
// what type should order.receiveHiredObject return here?
 类似资料:
  • 可以使用泛型将返回类型与参数类型匹配吗? 实例案例: 我有一个抽象类,可以从不同的POJO导入数据,这个类包含一个abstract方法importData。 importData返回的对象必须与传递给该方法的对象类型相同。 由于抽象方法的每个实现的对象类型不同,并且类型不扩展另一个,如何定义抽象方法,以便实现返回类型和传递类型必须匹配? 经过考验: 结果: 方法的返回类型不必与传递的对象类型匹配。

  • 我试图创建一个Java方法,它接受一个对象类型和它应该转换成的数据类型。 例如,如果我应该能够返回一个值1作为Int或双根据需要。我使用类传递数据类型作为参数。 问题:如何使方法泛型以接受基于输入参数的返回类型? 下面的代码只是一个示例,它可能在语法上不正确,用于解释我的问题。

  • 我想使返回数据类型的的函数与传入的参数的数据类型相同。例如,我会这样调用函数: 因为我将一个传递给,所以它返回了一个

  • 此外,是否可以说泛型通配符类型仅在方法的参数声明中才有意义?

  • 我在我的一个实用程序类中有一个方法,它接受一个集合和一个类对象,并返回一个Iterable实例,该实例可以遍历作为指定类实例的集合的所有成员。其签名为: 这对于大多数用例都非常有效,但现在我需要将其与泛型类