我正在嘗試創建一個將回傳泛型型別引數的方法。
我有一個類 VehicleOrder,它擴展了抽象類 Order。在 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 回傳一個物件而不是一個 VehicleOrder?如何改進回傳正確型別的方法?
謝謝,
uj5u.com熱心網友回復:
請注意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被宣告為回傳型別的東西。顯然,它不會那樣做。它回傳的內容取決于使用的子類。呼叫者無法決定它回傳什么!當您實作receiveHiredObjectin 時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?
uj5u.com熱心網友回復:
您可以將泛型型別宣告移動到類級別,例如:
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;
}
}
(認為??語法是正確的)
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/339397.html
