Вы не можете, не так, как вы используете ваши методы: <K> GenericValidation<K> from(Predicate<K> predicate)
.
Тем самым вы говорите разработчику, что он может передавать любые выражения Java: вы не можете проверить содержимое выражения во время выполнения, в отличие от того, что вы хотите поиграть с байт-кодом, чего у вас нет.
Вы должны применить это с помощью компилятора, например:
GenericValidation<K> fromNonNull(Predicate<K> predicate) {
return from(val -> val != null && predicate.test(val));
}
Или используя типы как показано ниже:
validateThat(employee.getFirstName()) // return a StringValidator1
.isNotNull() // return a StringValidator2
.isNotEmpty()
.hasLengthBetween(1, 100)
;
StringValidator1
имеет только isNotNull()
и возвращает StringValidator2
.
Вот так вы бы принудительно применили проверку isNotNull()
с помощью компилятора: вернув другой Тип предоставления большего количества услуг, чем по умолчанию. Поскольку StringValidator1
не имеет isNotEmpty()
, то компилятор сгенерирует ошибку компиляции, пытаясь вызвать ее.
Вы можете прочитать AssertJ код, чтобы узнать, как они работают с интерфейсом. Конечно, есть и другой свободный исходный код (и я думаю, что самая важная часть «свободного» - это то, что компилятор и IDE помогают проверять, что вы делаете).