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