Java通用继承“未经检查的转换”

时间:2019-04-24 12:03:10

标签: java oop inheritance design-patterns factory

我已经使用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);
    }

1 个答案:

答案 0 :(得分:0)

您的类的设计本质上是不安全的类型。具体来说,serveRequest方法:

public void serveRequest(PayData payData, PaymentType paymentType) {
    PayService<PayData> payService = (PayService<PayData>) payServiceFactory.getService(paymentType);
    payService.pay(payData);
}

无法强制payData的运行时类型与payService.pay所期望的兼容。根据{{​​1}},paymentType可能会在运行时返回getService,因此PayService<Anything>可能会在运行时返回任何类型。因为payService.pay应该是类型,所以只能在运行时知道,所以不能在编译时强制执行。

最好的办法是放一个payData并使SuppressWarnings通用:

payData