My general rule of thumb is that I use 'assert' whenever I'm claiming that
something must be true given static (non-runtime) knowledge local to the
context (usually a method or class).  If the assert fails, it indicates
that there is irrefutably a bug in that context.  I use the Preconditions
helpers for things that should be true, but might be outside the control of
a local context, or might be runtime-dependent.  In extreme situations I
might use an explicit if/throw new AssertionException if the consequences
of a hypothetical bug are so extreme that it doesn't make sense to ever
disable the assert (e.g. in a fireMissiles method).

In terms of assert/Preconditions vs DCHECK/CHECK: I think it's not exactly
a 1:1 comparison.  We quite frequently return error Status's for things
that we use Preconditions for in Java (illegal argument, illegal state). I
think that's appropriate, given the different error propagation paradigms
of Java vs. our flavor of C++.

Sorry if this doesn't actually suggest a resolution, I think it's a 'know
it when you see it' situation - both Preconditions and asserts have
appropriate uses.

- Dan

On Tue, Jul 11, 2017 at 12:49 PM, Alexey Serbin <[email protected]>
wrote:

> Hi,
>
> While working on a small refactoring in the Kudu Java client, I found that
> sometimes we use asserts
> and sometimes Preconditions [2] from the guava library to assert on the
> consistency of the code.
>
> As Todd suggested, I'm starting this thread to clarify on what is the best
> way to do perform
> the consistency checks in our Kudu Java client code.  Ideally, the desired
> outcome from the
> anticipated discussion would be some sort of guidance on assertion of the
> consistency constrains
> and invariants in our Java client code.  Once we have the guidance, we
> could put it as an
> additional section of our 'Contributing' page.
>
> The issue with the Java asserts is that they are not applicable unless the
> JVM is run with '-ea'
> flag, so it's not possible to explicitly stop processing further
> instructions in the context
> when an inconsistency is detected.
>
> To me, we have more clarity with the consistency checks and invariant
> assertion in our C++ code.
> We have CHECK- and DCHECK- derived macros to perform various types of
> consistency checks.  In short,
> the CHECK-related are always there, and the DCHECK-related ones are
> present only in debug builds.
> We don't turn on/off any of those dynamically in runtime.  Also, those C++
> asserts are kind of 'hard'
> ones -- the whole program is terminated and you don't need to think how to
> deal with the mess which
> isn't possible to recover from.  The latter one is a luxury which is not
> available in Java
> (correct me if I'm wrong).
>
> Putting the explicit termination of the whole program (with an optional
> coredump) aside,
> the Java's assert looks like DCHECK() but with the ability to turn it
> on/off using the run-time switch.
> Using guava's Preconditions gives us an option to address that and have a
> way
> to assert the consistency in our code even if code is run without the
> '-ea' JVM flag.
>
> So, to me it looks natural to use the Preconditions-derived checks for
> asserting on invariants
> even while running in production environment, while using asserts only in
> debug/test mode,
> asserting on programmatic errors and other non-crucial invariants which
> might be handled
> by the code even if those checks are removed.
>
> However, this simple approach contradicts to some points of [1] (which, by
> my understanding,
> is contradictory and very confusing as is).  Also, I'm not a Java
> programmer,
> so I might be missing some crucial points here.
>
> What do you think?  Your feedback is highly appreciated.
>
>
> Thanks,
>
> Alexey
>
>
> References:
>   [1] http://docs.oracle.com/javase/8/docs/technotes/guides/langua
> ge/assert.html
>   [2] https://github.com/google/guava/wiki/PreconditionsExplained
>
>
>
>

Reply via email to