Search code examples
javalambda

Why can't I use .orElseThrow with ::new in Java


hi here is my code using Java and JPA.

  Club club = clubRepository.findById(clubId).orElseThrow(
                () -> new ClubException(ClubErrorCode.INVALID_CLUB_ID)
        );

and I got a code review from my collegue that I could refactor that code like this.

() -> new ClubException(ClubErrorCode.INVALID_CLUB_ID) -> ClubException(ClubErrorCode.INVALID_CLUB_ID)::new

but it doesn't work. I am not familiar with lambda and Method Reference..

it is impossible to refactor like that? (using ::new)


Solution

  • Your colleague is wrong. ClubException(ClubErrorCode.INVALID_CLUB_ID)::new is not a valid method reference expression.

    Method reference expressions can take many forms, but there are only two forms that involve ::new. See the syntax in the language specification. The two forms are:

    ClassType :: [TypeArguments] new 
    ArrayType :: new
    

    In this case, the part before ::new is ClubException(ClubErrorCode.INVALID_CLUB_ID). This is neither a ClassType or an ArrayType.

    That said, ClubException::new would have been a valid method reference expression. If ClubException has an accessible parameterless constructor, then it is also valid to pass ClubException::new to orElseThrow. The parameterless constructor will be called to create a new instance of ClubException when the optional is empty.

    So if new ClubException() is equivalent to new ClubException(ClubErrorCode.INVALID_CLUB_ID), then passing ClubException::new would achieve what you want.

    Otherwise, you cannot use the ClassType::new form of an method reference expression.

    If you really want to use a method reference expression, you can declare a method that returns new ClubException(ClubErrorCode.INVALID_CLUB_ID) somewhere, and use an appropriate method reference expression to refer to that method:

    class SomeClass {
        public static ClubException newClubException() {
            return new ClubException(ClubErrorCode.INVALID_CLUB_ID);
        }
    }
    
    //
    
    ...orElseThrow(SomeClass::newClubException);