• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Tim Cooke
  • Liutauras Vilda
  • Jeanne Boyarsky
  • paul wheaton
Sheriffs:
  • Ron McLeod
  • Devaka Cooray
  • Henry Wong
Saloon Keepers:
  • Tim Holloway
  • Stephan van Hulst
  • Carey Brown
  • Tim Moores
  • Mikalai Zaikin
Bartenders:
  • Frits Walraven

Question about assertion

 
Greenhorn
Posts: 5
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I have a question about this statement in JAVA 2.
"Do not use assertions to validate arguments to a public method."
Does it just mean it's inappropriate if use assertions to validate arguments to a public method? will there be a compile error?
For example, in program below, it compils and runs ok.
public class aClass2
{
public void m1 (int value)
{
assert (value >= 0): "Value must be non negtive: value = " + value;
System.out.println("OK.");
}
public static void main(String [] args)
{
aClass2 foo = new aClass2();
System.out.println("aClass.aMethod (-1): ");
foo.m1(-1);
}
}
 
Ranch Hand
Posts: 456
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
yes, you are right, it will work, but you shouldn't do that.
The reasoning is this:
If you are using public method that means you are exposing the code to the outside. That means anyway can access that method, and therefore pass any data to it. This means you have no control over what is being passed in. When you are using assert statement, it means you want to verify that something is as expected. You can't do that with public methods, because although you may want a certain thing, you can not rely on another programmer/user to send that method what you are expecting. Only with private methods which are not exposed can you safely assume that you should get what you expect. The assert statement is to make sure that is indeed the case. Asserts should be used for test, not for production code.
 
Greenhorn
Posts: 3
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
" Asserts should be used for test, not for production code. "
Thanx,I've got it.
 
(instanceof Sidekick)
Posts: 8791
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
But that doesn't mean public methods should not validate their parameters. Never trust unknown clients which is everybody when you are writing a class for reuse. Just don't use assert to do it because it's intended that assert should be turned off in production.
 
Ranch Hand
Posts: 3061
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
You should use an if statement, or other appropriate control statement, to validate user input then perhaps throw an exception. Perhaps this hasn't been mentioned since it seems fairly obvious.
 
Ranch Hand
Posts: 268
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I have a slight disagreement with the good people at Sun on this one, I guess. I see nothing wrong with using asserts in a particular way, even in production code.
If you ascribe to the notion of preconditions and postconditions described by Design by Contract (DbC), then when you document methods you describe the precondition that every caller must meet as well as the state that method will leave the system in if the caller does meet that postcondition.
In my way of thinking, if the caller doesn't meet the precondition, then the behavior of the method is undefined. It could throw an AssertionError, some exception, enter an infinite loop, or call System.exit(). It could do anything...that's why preconditions must be spelled out precisely in the documentation for calling that method.
The time to use Java's normal exception mechanisms are the cases where the caller meets the precondition, but due to some unforeseen circumstance your method still cannot meet its advertised postcondition (could be the failure of some other system...maybe the database has inconsistent or incoherent data for example). These circumstances are "exceptional" conditions because they should not happen (the DB should not have inconsistent or incoherent data, obviously this is the result of some bug somewhere else) and they are not the caller's fault or the fault of your method up to that point.
Exceptions are useful in this context, because you have to keep in mind that there is very little you can say for certain about the caller and what they're trying to do big-picture. Your caller could be anything in the system, and you have no idea if this is a showstopper problem for that caller or not. So the best thing to do is describe the problem as best you can and throw the exception--if the caller is in a situation where they can accomplish their task in some other way, this allows them to do that, and you have no way of knowing whether they can go about their task in some other way.
If you look at things this way, you can quickly see that it is impossible and undesirable to write an assertion for the exceptional case described above. You'd have to assert every conceivable valid state for the entire system on every other line of code. Not practical. I'm of the opinion that it doesn't even make sense to assert in certain, specific instances that meet the above "exception" criteria...some people think, hey, I know the database has been acting up in this one particular way, so I'm going to write an assertion here. But if it's not the fault of the caller or your method's execution in the context of that call, then just throw an exception...you could end up throwing an AssertionError to a caller that could easily have handled the exception and gone on executing.
IMHO, the time to use assertions is to nail down the caller and your own method. That means, as long as you've listed the precondition of a method, you should be free to assert that precondition is true as soon as your method is entered. If the caller did not call your method properly by ensuring that the precondition is met, it is not unreasonable for your method to simply trundle along and let whatever problems that will happen, happen. After all, the caller did not live up to their responsibility. Much more helpful, though, is to perform the assertion that will specify the problem exactly, and since the behavior of your method is undefined if the precondition isn't met, this is a perfectly valid and helpful thing to do (above and beyond the call, even), as long as you've made the caller's responsibilities abundantly clear in the documentation.
This intersects the real world a bit harshly, though. You don't want AssertionErrors propagating to the top of your application if it's going to cause failure in a spectacular crash kind of way. Yet, having assertions enabled in production systems can sometimes nail down where exactly things are going wrong...I can't tell you the number of times I've worked on a complex system in which a NullPointerException is raised and it's not clear at all where that NPE originated (usually from a null record in the DB that was supposed to be set, at some time way earlier by a completely different system, to a non-null value...great, now you know what the problem is, but you still haven't a clue which bit of software is the one responsible for the bug!).
Most apps have a top-level handler for exceptions to catch them, log them explicitly, and continue functioning in whatever ways they can. I don't see any reason to do the same thing for assertions at an even higher level.

As long as a handler was built into the app with production scenarios in mind, I think it is equally valid to assert at the end of your method that your method does what you think it does.
There is the little matter now of performance--all of these checks no doubt will cause some apps to have bottlenecks in undesirable places. This is why I almost always write some kind of assertion class that performs the assertions for me along with some threshold int I pass in. That way, I can configure the Assertion class to skip all assertions below some threshold that I can dynamically configure in the runtime system. Furthermore, the Assertion class does nothing at all if I set an ASSERTION_DISABLE constant to true. In this way, I can compile out all that assertion code if I really want to max out performance, or I can leave it enabled and set the threshold to execute whatever assertions I want. I find that in 99% of the cases, there is little performance impact of leaving them on.
sev
[ February 27, 2004: Message edited by: sever oon ]
 
What a stench! Central nervous system shutting down. Save yourself tiny ad!
Gift giving made easy with the permaculture playing cards
https://coderanch.com/t/777758/Gift-giving-easy-permaculture-playing
reply
    Bookmark Topic Watch Topic
  • New Topic