ursus
07/22/2025, 9:03 PMrequire(x)
and check(x)
?ephemient
07/22/2025, 9:05 PMrequire
a precondition - throws IllegalArgumentException
check
an invariant - throws IllegalStateException
ursus
07/22/2025, 9:06 PMephemient
07/22/2025, 9:08 PMursus
07/22/2025, 9:09 PMDidier Villevalois
07/22/2025, 9:15 PMrequire
and check
are both preconditions assertions. However their intent are different.
require
denotes of a functional assertion, where you verify incoming parameters. You will use require
to verify parameters of a function or a constructor (inside an init
block).
check
denotes a state assertion, where you verify state changes of your system. You will use check
to verify whether a state-changing call on an object still maintains its invariants.
A way to remember this is indeed the thrown exception.ursus
07/22/2025, 9:17 PMMichael Krussel
07/22/2025, 9:22 PMcheck
is also used to see if an object is in a valid state for the operation it is trying to do (no state changed required)
I wouldn't use either of these functions for transforming data from an api object to domain objects. Instead the api object should be validated as good and report a API validation error if not. That could be part of the mapper and then the mapper should report that it can throw that specific error.
I see check
and require
as things to detect bugs in my code and not an API failure.
But in general if foo
cannot complete toBar
based on its state, that is a IllegalStateException
, if it cannot do it based on argument passed to toBar
then it is an IllegalArgumentException
.Didier Villevalois
07/22/2025, 9:37 PMfoo
should really be in its current state, or whether you should have `check`ed its state sooner. If `foo`'s current state is a valid state for a Foo
but is not conformant to what can be transformed to a Bar
, then maybe defining Foo::toBar
is not the right design. You could have a factory that takes `Foo`s as an argument and then can require
that theses Foo
have a valid shape to build a Bar
.ursus
07/22/2025, 9:38 PMephemient
07/22/2025, 9:39 PMursus
07/22/2025, 9:40 PMephemient
07/22/2025, 9:40 PMDidier Villevalois
07/22/2025, 9:40 PMrequire
. Maybe the constraints of your system are tighter than what's allowed in your data source.ursus
07/22/2025, 9:41 PMephemient
07/22/2025, 9:45 PMursus
07/22/2025, 9:46 PMDidier Villevalois
07/22/2025, 9:48 PMassert
but then it's an Error
, not an Exception
... 😆 An thrown Exception is something that can happen because of external conditions. A thrown Error is something that should not happen in a program. (Error would be a panic in Rust for instance, where Exception would be handled with a Result.)
And I know it's confusing because now we will have Error types which are really meant to model "normal" erroneous responses, whereas all exceptions will (ideally) be used for panics.ursus
07/22/2025, 9:49 PMerror(..)
, but then looking inside its illegal state, so == require 😄ephemient
07/22/2025, 9:52 PMassert
behavior depends on compile-time and run-time arguments, so I don't think it's ever a good choiceursus
07/22/2025, 9:53 PMephemient
07/22/2025, 9:56 PMursus
07/22/2025, 10:02 PMephemient
07/22/2025, 10:07 PMephemient
07/22/2025, 10:08 PMephemient
07/22/2025, 10:08 PMpython -O
skips assertions. the default is just the inverse of Javaursus
07/22/2025, 10:08 PMephemient
07/22/2025, 10:09 PMursus
07/22/2025, 10:13 PMDidier Villevalois
07/22/2025, 11:35 PMVampire
07/23/2025, 7:04 AM-ea
are intended to do additional checks to find program bugs during test execution which you don't want to execute at runtime to save performance afaiu.CLOVIS
07/23/2025, 7:19 AMyea but overall, why would someone want to disable them come productionIn the old days, software was very slow so checking repeatedly for the same things was expensive. One of the original reasons why Java has the reputation of being slow is that it checks for array indexes on each access.
assert
was meant as a way developers can have very extensive sanity checks everywhere in the program that are then disabled in production to avoid a performance impact.
It's similar to how Rust will check for overflows in development but will UB in productionCLOVIS
07/23/2025, 7:19 AM