java 8 switch case默认为类类型的break

我一直在寻找java的切换类型,我在这里找到了一个解决方案: 在java中切换类型

但问题是,解决方案并不像是一个带有breakswitch ,确定会发生这种情况,因为我循环使用了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 

它必须只打印第一行,而不是第二行匹配。

您只需要更改方法switchTypecaze以使用Predicate而不是Consumer ,因此循环可以在第一个匹配时停止。 其余代码不需要任何更改:

 @SafeVarargs private static void switchType(StripeObject so, Predicate... predicates) { for(Predicate predicate : predicates) if(predicate.test(so)) return; } private static  Predicate caze(Class clazz, Consumer consumer) { return obj -> { if(clazz.isInstance(obj)) { consumer.accept(clazz.cast(obj)); return true; } return false; }; } 

请注意,这仍然与switch语义不同,因为switch语句通常排除了模糊的情况。 这里,其中一种类型仍然可以是另一种类型的子类型,因此,与switch语句不同, case语句的顺序确实很重要。

如果所有情况都不同,这不是问题。