Why should I prefer checkState over assert? - java

Is there any benefit of using checkState over assert? I remember reading somewhere that I should prefer checkState but I can't remember why.

checkState and assert have totally different purposes.
checkState is a precondition check that throws an exception if a caller called your method when the program is in a state in which that method may not be called. (Meaning that they are using your code incorrectly; they should have been able to avoid calling that method at the wrong time by using it correctly.)
assert is generally at most a sanity check of something that you know must be true at that point in the program (kind of a compiled comment). Additionally, assert may be enabled or disabled depending on a flag when starting the JVM. It's typical to have it disabled in production. So it's not something you can rely on to break the flow of your method even if you do somehow get in a state that you're asserting is not possible.
Guava's new (as of 17.0) Verify class is something like an assert that is always enabled, but not exactly; it's for cases that should not occur, but could possibly if some outside service (i.e. one that your code is calling, not the code that's calling you) behaves in a way that it claims it shouldn't. See its Javadoc for more on the differences between Preconditions, assert and Verify.

Related

When is it suitable to throw an Exception?

I've seen some code recently where the author was throwing exceptions for almost every constructor and throwing runtime exceptions for things like the code below, in a method that returns int:
if(condition){
return 1;
}
if(condition){
return 2;
}
if(condition){
return 3;
}
throw new RuntimeException("Unreachable code");
// method ends here
I wouldn't have personally thrown an exception there, because I would have structured it using if and else if statements, and in this particular case your code would be fundamentally wrong for it not to satisfy one of the conditions anyway.
There are plenty of places you could throw runtime exceptions, that would never be reached if you're code is working correctly, sometimes it just seems like the author doesn't trust the code to work, in the case of the code block above. Also, every constructor could throw an exception for if it doesn't initialize correctly, but you could also structure it so that the object would be null - which you could then check for in main, for instance.
What I'm asking, basically, is when is it worth throwing an exception?
The point of exceptions is to communicate exceptional situations.
In that sense: if it is absolutely unexpected that all your conditions are false in your example, and that there is also no valid return value to indicate that situation, then throwing that RuntimeException is the reasonable thing to do here; but I would probably change the message to:
throw new RuntimeException("All conditions failed: " + some data)
As said: it is about communicating; in this case to the person debugging the problem. So it might be helpful here to include the information that is required to understand why exactly all those checks turned out false.
The point is: there is a contract for that method; and that contract should include such details. Meaning: if that method is public, you should probably add a #throws RuntimeException with a clear description.
And it is also a valid practice to use RuntimeException for such situations; as you do not want to pollute your method signatures with checked exceptions all over the place.
Edit: of course, balancing is required. Example: my classes often look like:
public class Whatever {
private final Foo theFoo;
public Whatever(Foo theFoo) {
Objects.requireNonNull(theFoo, "theFoo must not be null");
this.theFoo = theFoo;
So, there might be a NPE thrown from my constructors; yes. But: only there. All my methods can rely on the fact that all fields were initialized to non-null; and they are final, so they will always be non-null.
Meaning: one has to stay reasonable; and "develop" a feeling for: which problems are exceptional but possible; and which ones are so impossible that you don't pollute your code all over the place to check for them.
Finally; just to make that clear - adding exceptions is only one part of the equation. When something throws, then you need something to catch! Therefore, as said: balancing comes in. Whatever you do in your code has to "add value" to it. If your code doesn't fulfill a clear, defined purpose, then chances are: you don't need it!
GhostCat has basically covered all that need to be said when and why we should use exceptions. Just to take it further, the best thing to do is to weigh the cost benefit of including an exception. The cost in this context refers to performance as well as degraded client friendliness of the application while the benefit is the smooth running of the application as well as being user-friendly. In my opinion first one should distinguish between application and system error. Then these errors further need to be scrutinised after dichotomizing them into compile and runtime ( note that compile time errors normally do not need to be handled with exception but to debug and find out issues you need to handle them using debug tools such as assert of C++). Even if the nitty-gritty of inclusion of exception handlers depends on the context of the specific application, generally, one can postulate the following principles as a starting point:
1- Identify critical hotspot crash points of the code;
2- Distinguish between system and application errors;
3-Identify run time and compile time errors;
4- Handle compile time error using debugging tools such as assert or preprocessor directives. Also, include exception handlers or trace or debug to handle runtime errors
4-weigh the consequences of handling exceptions at run time;
5- Then provide a testable framework, which normally can be handled during Unit Test, to identify where exceptions need to be included or not.
6- Finally, decide where you need to include the exception handlers for your production code taking into account factors you think are decisive and need to include exception handler to handle them.
7- Finally finally .... you need to have a crash proof exception handler that should be triggered in the unlikely scenario that the application crashes and include fallback safety to handle states to make the application very user-friendly.

What exception to use to prevent a method from being called multiple times?

I have a method that should only be called once during an object's lifetime. In order to ensure that this is the case, the method sets a boolean flag in the Object to true so it can later check if this method has already run. I am currently throwing an IllegalArgumentException (with a descriptive message) if this method is called a second time during a single object's lifetime, but that doesn't feel quite right to me, since the problem is not actually with the arguments themselves. Is there a better exception to use than an IllegalArgumentException?
I chose not to use an assert statement in this case, because the class and method are both visible outside the package, so the problem may be caused by code outside of my package. Is that correct thinking?
Throw an IllegalStateException.
But since exceptions shouldn't be part of the ordinary control flow, you should add a companion method, which returns a boolean that indicates whether the next call to the method will be successful.
An example for such a companion method is Iterator#hasNext().
A well-designed API must not force its clients to use exceptions for
ordinary control flow. A class with a “state-dependent” method that
can be invoked only under certain unpredictable conditions should
generally have a separate “state-testing” method indicating whether it
is appropriate to invoke the state-dependent method. For example, the
Iterator interface has the state-dependent method next and the
corresponding state-testing method hasNext.1
1: from Effective Java, Chapter 9: Exceptions
What should worry you more than the specific exception type is the fact that you created a bad design here.
Good interfaces make it easy to do the right thing and hard to do the wrong thing.
Meaning: your current implementation makes it easy to call that method twice; respectively you now force your clients to always check if that method was already called.
So, instead of spending your time on the exception type: step back and figure how to dissect your one class into two classes for example. And find a nice so that calling that specific method gives you a different object to work on. Or check if you should rather use a state machine to solve this problem.

assertions in JavaFx and in general

In javaFx, we see the following statement in the initialize method of each generated controller class, for each control with fxid.
assert type != null : "fx:id=\"type\" was not injected: check your FXML file 'FinancialReport.fxml'.";
I can understand that the statement is there to ensure that, at the time this fxml is loaded the control with this fx:id is present in the fxml layout file, if the control is not present it throws an exceptions and quits the fxml loading process.
But then referring to this, I learned that assertions are not recommended to be used in production code. Again studying this tutorial, it seems that assertions are useful, especially when debugging (however, not to be used to validate the arguments of public methods).
I need more knowledge of the following :
Is it fine to use assertions for input validation and such purposes, in production code?
Can we do something else then the usual behavior when the Boolean expression turns false, like some alternative method call or something (an example would be nice).
Is it fine to use assertions for input validation and such purposes,
in production code?
No. Refer to the first link you posted (which actually says that assertions should never be triggered in production code, not that they should never be used): assertions are not even switched on by default when running the JVM. So your validation would fail most of the time. Assertions are specifically there as a debugging tool - to check that your code is correct. The assertions that are added in the generated controller code are good examples: they check that the #FXML-annotated fields in the controller have elements in the FXML file with matching fx:id attributes. If this fails, it's a programming error, not a data validation error.
Can we do something else then the usual behavior when the Boolean
expression turns false, like some alternative method call or something
(an example would be nice).
Just use an if (...) { ... } else { ... } construct?

When would you prefer to declare an exception rather than handling it in Java?

I know we can declare the exception for our method if we want it to be handled by the calling method. This will even allow us to do stuff like write to the OutputStream without wrapping the code in try/catch block if the enclosing method throws IOException.
My question is: Can anyone provide an instance where this is usually done where you'd like the calling method to handle the exception instead of the current method?
Edit: I meant calling method instead of super class in the last line.
In general, I would say design your exception flow so that the exception is caught by the code that can actually take appropriate action.
This usually means that in a "library" method (or, some kind of general utility method in a large project), you will be throwing exceptions not catching them.
On the other hand, if you have a situation where you find yourself declaring your method to throw an exception that you believe in practice will hardly ever occur (e.g. serialisation generally involves all sorts of spurious checked exceptions which in practice won't occur, e.g. if you're deserialising an Integer, it's really unlikely that the Integer class is not present, but you still have to catch the appropriate exception), then you have a third option of re-casting to a RuntimeException.
I guess by "super class" you mean the code that called your method.
If you expect the caller to know more about the problem compared to your method, than you can pass this responsibility up the calling stack.
In general, if you do not know how to handle the problem, don't. Ether pass it or wrap it in another exception.
If you can't handle the error at the point in a sensible way (e.g. displaying error message, taking an alternative path, etcetera), then just let it bubble up.
If you want the error to be handled at a different level of the application.
Here's a semi-concrete example. Let's say I've got a web application which is implemented as a series of states and actions. Suppose that, while a state is being processed, a database access causes an SQLException to be thrown. This would not happen during the normal operation of my application; it would only happen if there were something wrong with the database.
The method that access the database doesn't need to know what my procedure for handling semi-fatal errors like this is. That logic implemented at a higher level — in the method that processes the state — and it's essentially the same for any runtime error, whether it's literally a RuntimeException or not: spit out a nice-looking error message to the user telling them to contact tech support.
Imagine if I had to add a try/catch block performing this logic to every method that accessed the database and could possibly throw an SQLException. That's what's called a nightmare.
I have used expections to as part of transferring information between architectural layers of application.
For Example:
if the DAO (Database Access Layer) gets a SQLException it throws a customized DAOLayerException which is caught by the businesslayer which in turn throws an exception which is caught by the presentation layer.
This was for unchecked exceptions.
I usually follow the practice of throwing checked unchecked exceptions (not handling them) if the function is to be used by numerous caller or are unknown at the time of development of the function.
In web frameworks (like spring) you often let errors propagate and container will deal with them (by showing error page or message to the user, rolling back transaction, etc).
Also, there are lots of java errors you never catch, like OutOfMemoryError. You can catch them, but you can't deal with them properly.
You asked for an example, and here is a common one.
If you are writing code to read a particular file format, these normally declare IOException. The reason for this is that it might be used by a desktop app (which wants to put up a dialog box) or a text utility (which wants to write an error message) or a web app (which wants to return an error code). Exception handling allows you to do that.
Yes, I would declare it so it propagates up until a parent calling method which would actually handle it (display on UI, break there, ..)
For Instance, I may have some helper methods in a sendEmail method. If a helper method say checkEmailAddress() produced an exception, I would want sendEmail to know about it, which can further propagate it up or do an alert on UI "email is wrong"

.Net equivalent to Java's AssertionError

In Java, I will occasionally throw an AssertionError directly, to assert that a particular line will not be reached. An example of this would be to assert that the default case in a switch statement cannot be reached (see this JavaSpecialists page for an example).
I would like to use a similar mechanism in .Net. Is there an equivalent exception that I could use? Or is there another method that could be used with the same effect?
Edit - To clarify, I'm looking for a mechanism to flag failures at runtime, in released code, to indicate that there has been a (possibly catastrophic) failure of some invariant in the code. The linked example generates a random integer between 0 and 2 (inclusive) and asserts that the generated number is always 0, 1 or 2. If this assertion doesn't hold, it would be better to stop execution completely rather than continue with some unknown corrupt state of the system.
I'd normally throw InvalidOperationException or ArgumentOutOfRangeException depending on where the value came from.
Alternatively, there's Debug.Assert (which will only fail when you've got the DEBUG preprocessor symbol defined) or in .NET 4.0 you could use Contract.Fail, Contract.Assert or Contract.Assume depending on the situation. Explicitly throwing an exception has the benefit that the compiler knows that the next statement is unreachable though.
I'm not a big fan of Debug.Assert - it's usually inappropriate for a release (as it throws up an assertion box rather than just failing) and by default it won't be triggered in release anyway. I prefer exceptions which are always thrown, as they prevent your code from carrying on regardless after the opportunity to detect that "stuff is wrong".
Code Contracts changes the game somewhat, as there are all kinds of options for what gets preserved at execution time, and the static checker can help to prove that you won't get into that state. You still need to choose the execution time policy though...
You can use the Trace.Assert method, which will work on release builds (if you have the TRACE compilation symbol defined, which is defined by default on Visual Studio projects). You can also customize the way your application reacts on assertion errors by way of a TraceListener. The default is (unsurprisingly) the DefaultTraceListener, which will show the assertion in a dialog box if the application is running in interactive mode. If you want to throw an exception, for example, you can create your own TraceListener and throw it on the method Fail. You can then remove the DefaultTraceListener and use your own, either programmatically or in the configuration file.
This looks like a lot of trouble, and is only justifiable if you want to dynamically change the way your application handles assertions by way of the trace listeners. For violations that you always want to fail, create your own AssertionException class and throw it right away.
For .NET 4.0, I'd definetely look at the Contract.Assert method. But, this method is only compiled when the symbols DEBUG or CONTRACTS_FULL are defined. DEBUG won't work on release builds, and CONTRACTS_FULL will also turn on all other contracts checking, some of which you might not want to be present in release builds.

Categories

Resources