java 8 switch case默认为类类型的break
我一直在寻找java的切换类型,我在这里找到了一个解决方案: 在java中切换类型
但问题是,解决方案并不像是一个带有break
的switch
,确定会发生这种情况,因为我循环使用了Consumer
,我想知道一种修改我当前代码的好方法或清理替代方法来处理我的类类型, 在句柄第一次匹配后中断并且默认是仅处理不匹配(这里是父类StripeObject
)。
我的业务是处理来自webhooks的条带事件,我正在使用stripe-java ,所以我的代码现在是这样的:
public void handleWebHookEvent(Event eventJson) throws CardException, APIException, AuthenticationException, InvalidRequestException, APIConnectionException { Stripe.apiKey = configuration.getString(AppConstants.STRIPE_API_KEY); // Verify the event by fetching it from Stripe Event event = Event.retrieve(eventJson.getId()); Logger.debug(AppUtils.concatStrings("|-> Event Received: [", event.getId(), "] Type: [", event.getType(), "] Request ID: [", event.getRequest(), "]")); handleEventObject(event.getData().getObject()); } private void handleEventObject(StripeObject stripeObject) { switchType(stripeObject, caze(Customer.class, this::handleEventObject), caze(Card.class, this::handleEventObject), caze(Charge.class, this::handleEventObject), caze(Transfer.class, this::handleEventObject) caze(StripeObject.class, object -> Logger.debug(AppUtils.concatStrings("|--> !!! Not Handled StripeObject !!! [", object.toString(), "]"))) ); } private void handleEventObject(Customer customer) { Logger.debug(AppUtils.concatStrings("|--> Customer ID : [", customer.getId(), " ]")); } private void handleEventObject(Card card) { Logger.debug(AppUtils.concatStrings("|--> Card ID : [", card.getId(), " ]")); } private void handleEventObject(Charge charge) { Logger.debug(AppUtils.concatStrings("|--> Charge ID : [", charge.getId(), " ]")); } private void handleEventObject(Transfer transfer) { Logger.debug(AppUtils.concatStrings("|--> Transfer ID : [", transfer.getId(), " ]")); } @SuppressWarnings("unchecked") private static void switchType(StripeObject stripeObject, Consumer... consumers) { for (Consumer consumer : consumers) consumer.accept(stripeObject); } private static Consumer caze(Class clazz, Consumer consumer) { return obj -> Optional.of(obj).filter(clazz::isInstance).map(clazz::cast).ifPresent(consumer); }
在当前的代码中,如果evnet以Customer为例,它将打印:
|--> Customer ID ... etc
然后
|--> !!! Not Handled StripeObject !!! ... etc
它必须只打印第一行,而不是第二行匹配。
您只需要更改方法switchType
和caze
以使用Predicate
而不是Consumer
,因此循环可以在第一个匹配时停止。 其余代码不需要任何更改:
@SafeVarargs private static void switchType(StripeObject so, Predicate
请注意,这仍然与switch
语义不同,因为switch
语句通常排除了模糊的情况。 这里,其中一种类型仍然可以是另一种类型的子类型,因此,与switch
语句不同, case
语句的顺序确实很重要。
如果所有情况都不同,这不是问题。