the java assert mechanism: is it useful?

M

marlow.andrew

I am familiar with the idea of assertions, from my days with C/C++
(assert.h) and from what Bertrand Meyer says about them in OOSC(II).
And it seems to me that the java assert mechanism is similar. But I
reckon I would never use it for the same reason that I never used the
assert mechanism in C/C++. I preferred to throw an exception that
basically meant a fatal programming error has occurred. It would
always throw if triggered, there was not a mode for production that
made it a no-op. Checking was always on.

The reason I preferred a solution that always checked was because all
too often I come across code that contains assert compiled so that it
is turned off. The code goes wrong but the assertions designed to
detect this never trigger, the program just blows up or otherwise goes
bad.

So do people actually find the java assert mechanism useful? I am
relatively new to java and have not seen it used in any projects I
have been on yet. But I do see lots of advice telling newcomers to use
it and how good it is. Does anyone here prefer to always have the
checking on?

Regards,

Andrew Marlow
 
L

Lew

I am familiar with the idea of assertions, from my days with C/C++
(assert.h) and from what Bertrand Meyer says about them in OOSC(II).
And it seems to me that the java assert mechanism is similar. But I
reckon I would never use it for the same reason that I never used the
assert mechanism in C/C++. I preferred to throw an exception that
basically meant a fatal programming error has occurred. It would
always throw if triggered, there was not a mode for production that
made it a no-op. Checking was always on.

The reason I preferred a solution that always checked was because all
too often I come across code that contains assert compiled so that it
is turned off. The code goes wrong but the assertions designed to
detect this never trigger, the program just blows up or otherwise goes
bad.

So do people actually find the java assert mechanism useful? I am
relatively new to java and have not seen it used in any projects I
have been on yet. But I do see lots of advice telling newcomers to use
it and how good it is. Does anyone here prefer to always have the
checking on?

Assertions and exceptions have radically different purposes.

Exceptions are production-time mechanisms to detect anomalous
circumstances, like an interrupted connection or null pointer.
Assertions are a development-time mechanism to ensure algorithmic
correctness.

Assertions typically are disabled in production. Exceptions must not
be, and indeed cannot be.

Assertions verify that which is under the developer's control, like
the validity of arguments to a private method. Exceptions alert
operations staff to that which is not under the developer's control,
like the validity of arguments to a public method.

Assertions verify that which the programmer thinks that they've
guaranteed. For example,

public final void setFoo( Foo value )
{
if ( value == null )
{
final String msg = "null value passed to foo()";
throw new IllegalArgumentException( new
NullPointerException( msg ));
}
this.foo = value;
assert this.foo != null;
}
public final Foo getFoo()
{
assert this.foo != null;
return this.foo;
}

This example is somewhat trivial but illustrates that the assertion
represents the programmer's guarantee that 'getFoo()' cannot return
'null'. It guards against someone down the road commenting out the
'throw', for example, or adding another method that nulls the
attribute. Another use case places an assertion after the call to a
polymorphic method, where the risk is that a subclass might violate a
program invariant.

Invariants are what assertions enforce. Invariants are points in an
algorithm where one can state with certainty ("assert") that a
necessary condition is true.

There's good material on the Sun web site explaining the value of
'assert', and when to use or not use it.
 
T

Tom Anderson

So do people actually find the java assert mechanism useful? I am
relatively new to java and have not seen it used in any projects I have
been on yet. But I do see lots of advice telling newcomers to use it and
how good it is. Does anyone here prefer to always have the checking on?

I haven't ever used it.

I think the way to think of java assertions is as tiny unit tests which
are embedded in the application code. If you had a class like:

public class OldMoney {
private int pounds ; // must be >= 0
private int shillings ; // must be >=0, <20
private int pence ; // must be >=0, <12

public int getPriceInPence() {
return (((pounds * 20) + shillings) * 12) + pence ;
}
}

You might write a unit test that looked like:

public void testMoneyComponentCounts() {
OldMoney cash = somehowGetSomeMoney() ;
assertGreaterThanZero(cash.getPounds()) ;
assertInBetweenInclusive(0, cash.getShillings(), 19) ;
assertInBetweenInclusive(0, cash.getPence(), 11) ;
}

With assertions, you could write:

public int getPriceInPence() {
assert pounds >= 0 ;
assert (shillings >= 0) && (shillings < 20) ;
assert (pence >= 0) && (pence < 12) ;
return (((pounds * 20) + shillings) * 12) + pence ;
}

Which would do much the same thing, but would run every time you called
that method, if you had assertions switched on.

It'd be nice if you could write assertions at class rather than method
level, and have them evaluated, say, every time a method on an object of
that class was called. Like:

public class OldMoney {
private int pounds ; // must be >= 0
assert pounds >= 0 ;
private int shillings ; // must be >=0, <20
assert (shillings >= 0) && (shillings < 20) ;
private int pence ; // must be >=0, <12
assert (pence >= 0) && (pence < 12) ;
}

The compiler would deal with them in a similar manner to field initializer
expressions - collect them together and invisibly prepend them to every
method body. Or perhaps the end of every method body. Or both. Who knows.

tom

--
Imagine a city where graffiti wasn't illegal, a city where everybody
could draw wherever they liked. Where every street was awash with a
million colours and little phrases. Where standing at a bus stop was never
boring. A city that felt like a living breathing thing which belonged to
everybody, not just the estate agents and barons of big business. Imagine
a city like that and stop leaning against the wall - it's wet. -- Banksy
 
M

Marcelo Morales

So do people actually find the java assert mechanism useful?

You can see that people are actually using assertions:
http://docs.jboss.com/seam/2.0.3.CR1/reference/en-US/html/testing.html#d0e20144

I always keep assertions turned off, except for coding and testing
time. I guess most people work like that. My code does not have a lot
of assertions. In fact, I only use assertions when the test is
somewhat expensive, otherwise the if (...) throw new
RuntimeException(...) works just allright.


Regards,

Marcelo Morales
 
A

Arne Vajhøj

I am familiar with the idea of assertions, from my days with C/C++
(assert.h) and from what Bertrand Meyer says about them in OOSC(II).
And it seems to me that the java assert mechanism is similar. But I
reckon I would never use it for the same reason that I never used the
assert mechanism in C/C++. I preferred to throw an exception that
basically meant a fatal programming error has occurred. It would
always throw if triggered, there was not a mode for production that
made it a no-op. Checking was always on.

The reason I preferred a solution that always checked was because all
too often I come across code that contains assert compiled so that it
is turned off. The code goes wrong but the assertions designed to
detect this never trigger, the program just blows up or otherwise goes
bad.

So do people actually find the java assert mechanism useful? I am
relatively new to java and have not seen it used in any projects I
have been on yet. But I do see lots of advice telling newcomers to use
it and how good it is. Does anyone here prefer to always have the
checking on?

Useful feature.

That I am not using as much as I should.

:)

Arne
 
A

Arne Vajhøj

Tom said:
I haven't ever used it.

I think the way to think of java assertions is as tiny unit tests which
are embedded in the application code. If you had a class like:

public class OldMoney {
private int pounds ; // must be >= 0
private int shillings ; // must be >=0, <20
private int pence ; // must be >=0, <12

public int getPriceInPence() {
return (((pounds * 20) + shillings) * 12) + pence ;
}
}

You might write a unit test that looked like:

public void testMoneyComponentCounts() {
OldMoney cash = somehowGetSomeMoney() ;
assertGreaterThanZero(cash.getPounds()) ;
assertInBetweenInclusive(0, cash.getShillings(), 19) ;
assertInBetweenInclusive(0, cash.getPence(), 11) ;
}

With assertions, you could write:

public int getPriceInPence() {
assert pounds >= 0 ;
assert (shillings >= 0) && (shillings < 20) ;
assert (pence >= 0) && (pence < 12) ;
return (((pounds * 20) + shillings) * 12) + pence ;
}

Which would do much the same thing, but would run every time you called
that method, if you had assertions switched on.

There is a difference in that assertion can be used to test on
stuff that is not exposed to the outside.
It'd be nice if you could write assertions at class rather than method
level, and have them evaluated, say, every time a method on an object of
that class was called. Like:

public class OldMoney {
private int pounds ; // must be >= 0
assert pounds >= 0 ;
private int shillings ; // must be >=0, <20
assert (shillings >= 0) && (shillings < 20) ;
private int pence ; // must be >=0, <12
assert (pence >= 0) && (pence < 12) ;
}

The compiler would deal with them in a similar manner to field
initializer expressions - collect them together and invisibly prepend
them to every method body. Or perhaps the end of every method body. Or
both. Who knows.

Then you will need some type of AOP.

If the values tested are exposed, then it should be easy.

If they are internal you will need a very advanced AOP
framework.

Arne
 
M

marlow.andrew

Exceptions are production-time mechanisms to detect anomalous
circumstances, like an interrupted connection or null pointer.
Assertions are a development-time mechanism to ensure algorithmic
correctness.

Yes, I agree.
Assertions typically are disabled in production.  

They are with the java assert keyword. But I am asking if people
actually like it this way.
Invariants are what assertions enforce.  Invariants are points in an
algorithm where one can state with certainty ("assert") that a
necessary condition is true.

Indeed. I appreciate your answer but it shows that I failed to mention
something at the beginning. When I am using C++ (sorry guys) I use a
macro like MY_ASSET(expression) to make it clear that conceptually I
am asserting an invariant. But the macro expands to code that throws a
special exception (AssertionFailure) if the assertion fails. I think
it is important that code makes it clear whether it is asserting or
throwing, even though with my approach an assertion failure is
implemented as a throw.

-Andrew Marlow
 
Joined
Aug 5, 2008
Messages
3
Reaction score
0
In my opinion you would use assertion only in places where you are 100% sure the value of a something.

You just use assertion in development time just to make sure all your assumptions are 100% correct.
 
T

Tom Anderson


That's a rather interesting case - they use java assertions *in their unit
tests*, instead of JUnit's Assert class. There's no sign in that document
of the use of java assertions within the application code.
I always keep assertions turned off, except for coding and testing
time. I guess most people work like that.

That's pretty much what Sun designed assertions for.
My code does not have a lot of assertions. In fact, I only use
assertions when the test is somewhat expensive, otherwise the if (...)
throw new RuntimeException(...) works just allright.

That, on the other hand, is probably the wrong way to think about it. What
kind of conditions are you testing?

tom
 
T

Tom Anderson

There is a difference in that assertion can be used to test on stuff
that is not exposed to the outside.

Quite true.

The unit test addict would respond that there should never be stuff that
isn't exposed so that the test system can reach it - designing for
testability is a pillar of unit test dogma.
Then you will need some type of AOP. If the values tested are exposed,
then it should be easy. If they are internal you will need a very
advanced AOP framework.

I was just thinking that the compiler would do it. No aspect funkiness
required.

tom
 
L

Lew

They are with the java assert keyword. But I am asking if people
actually like it this way.

Well, the fact that they typically are is evidence that they do, is it
not?

Whether one likes it or not is not actually relevant. There are
objective reasons to turn assertions on or off, a decision made by the
operations staff as pointed out upthread. Assertions can be enabled
or disabled at a pretty fine-grained level; it's not just all-or-
nothing for the application.

The question isn't whether one "likes to turn assertions on", but when
it's useful to do so.

That depends in part on whether the programmer was smart enough to use
assertions for the correct purpose, and not as some sort of substitute
for exceptions.

There really is plenty of material on Sun's site and elsewhere as to
how to use assertions correctly. There is no excuse to use them
improperly.

GIYF.
 
R

Roedy Green

So do people actually find the java assert mechanism useful?

The is a distinction. When an assert fails, the PROGRAMMER has
screwed up. There is no point in continuing. It might just make
matters worse.

When you get an exception, the data may be bad, or the OS resources
may have run out, but the program is functioning perfectly.
 
C

Christian

So do people actually find the java assert mechanism useful? I am
relatively new to java and have not seen it used in any projects I
have been on yet. But I do see lots of advice telling newcomers to use
it and how good it is. Does anyone here prefer to always have the
checking on?

Regards,

Andrew Marlow


I do find it less useful. Some if-statements throwing Exceptions is
something I really prefer. Using asserts leads to people (and self)
disabling them which is imho a matter of premature optimization.

Christian
 
M

Mark Rafn

Christian said:
I do find it less useful. Some if-statements throwing Exceptions is
something I really prefer.

Do both, for different purposes.

Throwing an exception is for times when something has been misused or the
worldstate is different than you expect and you want the app to handle it.

Asserting is a verification of your own logic, making sure that your code
does what you think it does. It shouldn't be handled by the app, it should
cause a crash (well, at least an ugly event with a stack trace).

The purpose of an assert is to escalate a subtle logic bug into an
obvious crash bug. The purpose of exceptions is to handle unusual
situations at the right level as gracefully as possible.
Using asserts leads to people (and self)
disabling them which is imho a matter of premature optimization.

Funny, I do the opposite. I leave them on unless there's a particular reason
to turn them off for a class/package. correctness > performance
 
A

Arne Vajhøj

Tom said:
Quite true.

The unit test addict would respond that there should never be stuff that
isn't exposed so that the test system can reach it - designing for
testability is a pillar of unit test dogma.

I don't think that is applicable.

You unit test for the contract that the class exposes.

You do not unit test the internals of the implementation.

Assertions can be used for the internals stuff.
I was just thinking that the compiler would do it. No aspect funkiness
required.

The compiler will do it if you write the code everywhere.

But to write something once and get it applied to all methods
will bring it over in the AOP area.

Arne
 
M

marlow.andrew

Thanks for highlighting that. This gives me a good argument for using
an assertion mechanism in my C++ code that checks at runtime whether
or not to ignore assertion failures.

-Andrew
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,994
Messages
2,570,222
Members
46,810
Latest member
Kassie0918

Latest Threads

Top