简体   繁体   English

Java:如何使用方法引用在可选的 ifPresent 中抛出异常或在 ifPresent 中使用可运行对象

[英]Java: How to throw an exception in optional ifPresent using method reference or use a runnable in ifPresent

I would like to simulate an optional.ifPresentThrow() to use somenthing like:我想模拟一个 optional.ifPresentThrow() 来使用类似的东西:

.ifPresent(MyException::go)

and not use:并且不使用:

.ifPresent(e -> {
   throw new MyException();
})

so I created my class with the go method:所以我用 go 方法创建了我的 class :

class MyException extends RuntimeException {
   static void go() {
      throw new MyException();
   }
}

it's not work because the ifPresent hopes to receive a consumer x -> (), not a runnable () -> ()这是行不通的,因为 ifPresent 希望接收消费者 x -> (),而不是可运行的 () -> ()

adding some param to the function, I will have a unused param.向 function 添加一些参数,我将有一个未使用的参数。

what's the best way to do this?最好的方法是什么?

As you've already understood, Functional interface doesn't match - ifPresent() expects a Consumer<? super T>正如您已经了解的那样,功能接口不匹配 - ifPresent()需要一个Consumer<? super T> Consumer<? super T> . Consumer<? super T> But MyException::go isn't a consumer, since go() doesn't take any arguments.但是MyException::go不是消费者,因为go()不接受任何 arguments。

To fix it, you need to change the method signature of go() :要修复它,您需要更改go()的方法签名:

public class MyException extends RuntimeException {
    static void go(Object o) {
        throw new MyException();
    }
}

Note: it's only a dummy example.注意:这只是一个虚拟示例。

Usually, when you're creating a custom Exception you're having in mind a particular use case , and this exception would not be something ubiquitous like standard exceptions (for instance, if you have a need to create your custom subclass of AuthenticationException you would not expect it to be thrown in any part of your application, it might only occur while validating authentication data of the request).通常,当您创建自定义异常时,您会想到一个特定的用例,并且此异常不会像标准异常那样普遍存在(例如,如果您需要创建AuthenticationException的自定义子类,您会不要期望它会在应用程序的任何部分中抛出,它可能仅在验证请求的身份验证数据时发生)。

Let's expend the example shown above.让我们扩展上面显示的示例。

Assume we have a domain class:假设我们有一个域 class:

@Getter
public class MyCustomObject {
    private String name;
}

And MyException is designed to describe abnormal situations which might occur while using MyCustomObject or its subclasses. MyException旨在描述在使用MyCustomObject或其子类时可能发生的异常情况。 Argument expected by go() can be used to incorporate some properties of the domain object into the exception-message: go()预期的参数可用于将域 object 的某些属性合并到异常消息中:

public class MyException extends RuntimeException {
    public MyException(String message) {
        super(message);
    }

    static void go(MyCustomObject o) {
        throw new MyException(o.getName());
    }
}

Example of usage:使用示例:

Stream.of(new MyCustomObject("A"), new MyCustomObject("B"))
    .filter(o -> !o.getName().matches("\\p{Upper}")) // retain instances having Invalid names
    .findFirst()
    .ifPresent(MyException::go); // invalid name was found -> throw an Exception with the name included into a message

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM