[英]Java generic inheritance “unchecked cast”
我已經使用Java泛型實現了一個簡單的付款處理系統。 它可以在運行時進行編譯和運行,但是我對“未經檢查的轉換”警告感到困惑。
enum PaymentType {
CARD, SAVED_CARD
}
interface PayData {
}
class CardPayData implements PayData {
private String cardNumber;
private String cvc;
}
class SavedCardPayData implements PayData {
private String cardId;
}
interface PayService<T extends PayData> {
void pay(T payData);
}
class CardPayService implements PayService<CardPayData> {
@Override
public void pay(CardPayData cardPayData) {
// i need concrete class CardPayData here
}
}
class SavedCardPayService implements PayService<SavedCardPayData> {
@Override
public void pay(SavedCardPayData payData) {
// i need concrete class SavedCardPayData here
}
}
class PayServiceFactory {
private CardPayService cardPayService = new CardPayService();
private SavedCardPayService savedCardPayService = new SavedCardPayService();
public PayService getService(PaymentType paymentType) {
if (paymentType.equals(PaymentType.CARD))
return cardPayService;
else
return savedCardPayService;
}
}
class PaymentProcessor {
PayServiceFactory payServiceFactory = new PayServiceFactory();
public void serveRequest(PayData payData, PaymentType paymentType) {
// here i have 'unchecked cast' warning
PayService<PayData> payService = (PayService<PayData>) payServiceFactory.getService(paymentType);
payService.pay(payData);
}
}
試圖擺脫這種警告的任何嘗試都會導致我出現編譯錯誤。 例如,我嘗試從我的工廠方法返回泛型類型,但只收到編譯錯誤:
// return generic
public PayService<? extends PayData> getService(PaymentType paymentType) { ... }
public void serveRequest(PayData payData, PaymentType paymentType) {
PayService<? extends PayData> payService = payServiceFactory.getService(paymentType);
// error here:
// pay (capture <? extends PayData>) in PayService cannot be applied to (PayData)
payService.pay(payData);
}
類的設計本質上是不安全的類型。 具體來說, serveRequest
方法:
public void serveRequest(PayData payData, PaymentType paymentType) {
PayService<PayData> payService = (PayService<PayData>) payServiceFactory.getService(paymentType);
payService.pay(payData);
}
無法強制payData
的運行時類型與payService.pay
期望的兼容。 根據paymentType
, getService
可以在運行時返回PayService<Anything>
,因此payService.pay
在運行時可以期望任何類型。 由於payData
應為的類型只能在運行時知道,因此您不能在編譯時強制執行。
您能做的最好的就是放置一個SuppressWarnings
並使payData
通用:
@SuppressWarnings("unchecked")
public <T extends PayData> void serveRequest(T payData, PaymentType paymentType) {
PayService<T> payService = (PayService<T>) payServiceFactory.getService(paymentType);
payService.pay(payData);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.