簡體   English   中英

Java通用繼承“ unchecked cast”

[英]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期望的兼容。 根據paymentTypegetService可以在運行時返回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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM