简体   繁体   English

Java通用继承“ unchecked cast”

[英]Java generic inheritance “unchecked cast”

I've implemented a simple system of payment processing using java generics. 我已经使用Java泛型实现了一个简单的付款处理系统。 It compiles and works at runtime, but i confused by the "unchecked cast" warning. 它可以在运行时进行编译和运行,但是我对“未经检查的转换”警告感到困惑。

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

Any attempts to move away from such warning lead me to compiltation errors. 试图摆脱这种警告的任何尝试都会导致我出现编译错误。 For example i've tried to return generic type from my factory method, and received nothing but compilation error: 例如,我尝试从我的工厂方法返回泛型类型,但只收到编译错误:

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

The design of your classes is inherently type unsafe. 类的设计本质上是不安全的类型。 Specifically, the serveRequest method: 具体来说, serveRequest方法:

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

There is no way of enforcing that the runtime type of payData is compatible with what payService.pay expects. 无法强制payData的运行时类型与payService.pay期望的兼容。 Depending on paymentType , getService could return PayService<Anything> at runtime, so payService.pay could expect any type at runtime. 根据paymentTypegetService可以在运行时返回PayService<Anything> ,因此payService.pay在运行时可以期望任何类型。 Because the type that payData should be can only be known at runtime, you can't enforce it at compile time. 由于payData应为的类型只能在运行时知道,因此您不能在编译时强制执行。

The best you can do is to put a SuppressWarnings and make payData generic: 您能做的最好的就是放置一个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