This question already has answers here:
Closed 11 years ago.
Possible Duplicates:
Assert keyword in java
assert vs. JUnit Assertions
I use JUnit for unit testing, but a lot of times its hard to get at certain things with JUnit. I have recently started looking at Java assert.
Is it a good idea to use assert and how would you recommend using it?
The most important thing to note is that using assertions and testing your code are two different (if perhaps related) tasks.
I think the assertions docs pretty much explain the kind of situations to use assertions.
Assertions are popular in languages without exception handling, for making checks to ensure the program is operating correctly, so as to make problems easier to diagnose.
However there can be some ambiguity as to what the most appropriate cause of action is if an assertion fires. If the program exits immediately, there may have been a wasted opportunity to handle the failure more gracefully (e.g. reporting the failure to the user and attempting to recover data). If the program does not exit immediately, it could be in an unknown state because of the error, which is also undesirable.
As a result it is considered better practice to throw exceptions in Java when a given condition fails, which allows a best-of-both-worlds solution to these problems. For errors that can occur during normal operation of the program, checked exceptions most appropriate. Calling code is obliged to handle these errors. For errors caused by failure internal program logic, throwing a RuntimeException would allow the program to handle the failure appropriately further up the call stack.
Asserts do have one benefit which is they can be employed in development, but can be 'compiled out' for a consumer or release build, where speed of execution is more of a priority than early detection and handling of errors. However apps that require that characteristic are not commonly built in Java (more likely C++), which is again why assert is rare in Java.
(Also, I believe that assets at runtime are not always enabled by default by some IDEs anyway, so it is easy to have an assertion fail and not know about it.)
Yes it can be useful to use assert to verify the correctness of your program run-time. I would typically use it to catch errors according to the fail-fast principle to actively detect bugs.
A typical use case would be that an operation succeeded. Consider the following sample:
int nChanges = database.update(..);
assert(nChanges == 1);
I wouldn't consider using it for parameter validation or any such operation which should be validated in regular code according to the contract, since it doesn't throw the appropriate exceptions (and run-time exceptions can be mean). Similarly I wouldn't use it in testing since JUnit already offers assert mechanisms which in contrast to regular assert statements cannot be disabled.
Related
I have a project in which certain data has invariants which are not enforceable using language constructs, but I've intended to write my code such that they are maintained. If they are for some reason broken, it means that my code is buggy. I have some sanity check code which can discover if these invariants have been broken, but I'm not sure what is the canonical Java approach to responding to such a condition - is there some standard exception that I should throw? Use an assert?
Note that this is an issue of a value being set incorrectly at some point. The error itself does not occur at the time of the sanity check, but rather it occurred in the past, and the sanity check is just now discovering it (ie, it's not bad that the sanity check itself is running, it's just bad that the check failed).
Thanks!
Throw an IllegalStateException. It is meant specifically for purposes like this.
Deciding how your application would react to a broken invariant would be a sensible first step
In case a broken invariant is unrecoverable and basically means a bug a code, i second an answer about IllegalStateException.html (you may want to add some useful context for debug purposes ,e.g. variables in broken invariant) - such unchecked exception would stop a running thread
In case you can recover from broken invariant (by replacing some arguments with sensible default, giving it a second try) - you may want to throw a checked exception and catch it on one of upper layers and execute plan B
When would you want to propagate an exception to another Class/Method versus catching the Exception in the same Class/Method?
You catch the exception where you have to handle it.
As a rule of thumb, you should let your exceptions bubble up, but if you don't want your subroutine to crash due to a (possibly expected) error, than you handle the exception, which normally involves logging an error and/or displaying an error message to the user.
The good practice is "throw early and catch late". That allows you to better understand the cause of the exception.
This topic is fairly broad; fortunately there are good resources already in place:
Guidelines on Exception propagation (in Java)
http://www.javacodegeeks.com/2012/04/exception-handling-guidelines-best.html
Best practices for exception management in Java or C#
The great majority of exceptions occuring in real-life code are not recoverable in the sense there's any meaningful code that will retry the operation or try to do it differently. The only recovery happening is aborting the current unit of work in an orderly manner—logging the exception, releasing any resources and similar.
This means that, as a first rule, you'll always want to propagate the exception towards that well-defined exception barrier that demarcates your unit of work.
If your code demands anything different than this, it is probably going to be obvious enough, so you don't need to think about it in the general.
Does java has library exception class which means actually not an error, but good termination? I know I can make my own class or use null, but wish to know.
EDIT 1
I want to use exception object as an old fashion return code for a method, so I need something equivalent to ERROR_SUCCESS code in Win32 API.
Exceptions in Java are meant to be used for abnormal termination only. Using them to flag correct termination should be considered really bad practice.
You might use return values instead.
To directly answer your question: No. There is no standard Java exception that means "this is a normal termination".
If you wanted to, you could define a custom exception that meant this for your application.
However,
... using an exception for "normal control flow" goes against the strong recommendations of the Java designers, and a Java "Best Practice" rule that has pretty much universal acceptance. This is not to say you should NEVER do this. It is just that the cases where it is justifiable to do this are VERY RARE. (And you'd need to take special steps to avoid grossly inefficient code ... )
Anyway, the fact that it is (almost) always a terrible idea to use exceptions for normal flow control explains why a standard exception was never created. The Java designers clearly didn't want to appear to be encouraging this practice.
The closest thing to a "good termination" signal I can think of is not an exception, but a call to System.exit(int) with 0 as argument, to indicate to the operating system that the program ended successfully. From the javadocs:
Terminates the currently running Java Virtual Machine. The argument serves as a status code; by convention, a nonzero status code indicates abnormal termination. This method calls the exit method in class Runtime. This method never returns normally.
As has been pointed out, an exception is not to be used to inform of a "good termination", quite the contrary.
No. Exception means exceptional situation. You should structure your program flow so that exceptions are thrown only for exceptional situations, rather than on the normal flow.
So, if you want to return "success": return true or some enum Result.SUCCESS.
Exceptions are mean to denote that something went wrong. Different exceptions depict different items which went wrong and will thus cause the program to terminate if not handled. Something successfully finishing is not an exception.
I think what you need to do is to either return a particular value, or else, make your application fire some sort of event. In this case throwing exception is not (at least for me) recommended.
Depends what you define as "good termination" I guess - is a security exception good because it stopped someone from hacking your system? It's not really an error, but it is an abnormal situation that you need to handle.
In general exceptions are designed to be used for exceptional conditions only (which may or may not be an error in your code - it could mean that some resource is unavailable, or a security check failed etc.)
If you are using exceptions for regular control flow (i.e. they are getting thrown in normal, expected circumstances) then you are probably doing something wrong.
Maybe you mean an InterrupedException? This one is thrown, when you wish to terminate a thread gracefully.
As some other responses said, when there is no exception, nothing is raised.
Therefore, you can just your code for the "no-exception" into the try block after the rest of instructions. Something like:
try{
//code here
//code of no exception
}catch(Exception e){
//nothing or exception code
}
or you can just create your own exception by doing a class that extends Exception
Checked exceptions need to be caught or declared to be thrown at compilation time but runtimeexceptions need not ...why we give important only to checked exception ...
In Java, the original inventors of the language wanted to distinguish between common types of exceptions, which may occur in a program. They came up with these three types:
Checked exceptions are used for errors, which may occur at run-time and are expected (sort of), for example, IOException. When doing file or network I/O, for example, an error may occur at any time (disk full, connection lost, etc.) The programmer has to be aware, that any operation called may fail at any time, and thus, the language enforces this kind of awareness by forcing the programmer to do something about the exception.
Unchecked exceptions are used for programming errors, such as NullPointerException, IllegalArgumentException, etc. These errors are usually the result of an oversight of the programmer, and constitute bugs in the program. They should not be handled by most parts of the code, as all guarantees about the state, the program is currently in and its consistency, are gone. One of the distiguishing features of a run-time exception is, that it is unexpected (you don't really expect there to be a bug in your program, right? -- except on the general level of "of course, I would not bet my life on this program being bug-free")
Errors, from which a recovery is hardly possible, such as OutOfMemoryError, AssertionError, etc. These exceptions are the really bad ones. These guys are usually never handled, and if they occur, will cause the program to crash.
Of course, in practice, many application will handle run-time exceptions (at least by logging them), and even Errors. And frameworks like Spring tend to blur the distinction further by making all exceptions unchecked (i.e., run-time exceptions) anyway. Interestingly, checked exceptions were considered for inclusion in C# and omitted, because they add a heavy burden on the programmer. Opinions vary on that topic, even today.
Taken from http://en.wikipedia.org/wiki/Exception_handling
Unchecked exception types should not
be handled except, with consideration,
at the outermost levels of scope.
These often represent scenarios that
do not allow for recovery:
RuntimeExceptions frequently reflect
programming defects,[19] and Errors
generally represent unrecoverable JVM
failures. The view is that, even in a
language that supports checked
exceptions, there are cases where the
use of checked exceptions is not
appropriate
Clearly mentions that it represents scenarios that do not allow for recovery
The division gives you flexibility: when thinking what kind of exceptions to throw, you should throw checked exceptions only when the application can reasonably recover from them (for example: "can't write file" is rarely a good reason to crash; rather, let's show a message to the user). Runtime exceptions are supposed to be fatal (programming errors), so it's better to let the program crash right away.
It was supposed to be a good idea. But it's just too complex in practice. The core problem is that the library and language designers are supposed to decide what kind of errors are fatal to an application (which doesn't even exist at that time!).
Did you know that while 1 / 0 results in ArithmeticException, 1.0 / 0 is a perfectly legal Infinity? Obvious - or not... And java.text.Format is supposed to convert an arbitrary object to String, but for some reason it throws an unchecked exception (IllegalArgumentException) if the object to be converted is somehow wrong type (e.g. null), so in practice you must remember to write a try-catch block whenever you use Format. Obviously someone thinks that converting nulls to strings is a fatal programming error. I would rather return an empty string. Your mileage may vary. The JDK is full of this kind of weird choices, and it clearly shows the problem of choosing between checked vs. unchecked.
This problem has made many people advocate unchecked exceptions only. I think it's just silly; most exceptions should be taken care of, because they signal something important. If I was a language designer, I would make all exceptions checked, but instead of a try-catch -block, one could use a plain annotation to say "I don't care about this exception" (which essentially would convert that checked exception into a runtime exception). This would give the benefits of checked exceptions (nothing goes unnoticed unless explicitly told so) AND the benefits of unchecked exceptions (no heavy try-catch blocks all around). It would be the application programmer's call to decide what's fatal and what's expected.
Of course, you can catch runtime exceptions if you want to. A plain catch(Exception ex) does it.
Look at the name of the exception "RunTime".
At compile time the compiler can see exactly what and where things can go wrong with most of your code.
However some objects/values can only be evaluated at run-time and unfortunately the compiler cannot foresee this.
e.g. casting an object to int, when it is in fact a string. You can only determine it at run-time. Thus a run-time exception will be thrown
Have a look at the common RuntimeExceptions:
ArithmeticException
ArrayIndexOutOfBoundsException
ClassCastException
EmptyStackException
IllegalArgumentException
IllegalMonitorStateException
NullPointerException
UnsupportedOperationException
Practically speaking: Most of those exceptions can occure everywhere and are most likely a programmers error, and as such are only needed to be handled in some kind of bug reporting handler. Other Exceptions show problems with the environment of the JVM, and need to be handled, because they cannot be guaranteed no to be thrown be the program alone.
if exception occurred at runtime then immediately JVM creates exception object and that object message is printed on console.
unchecked exceptions are occurred due to poor logic of our program.so program will be terminated abnormally.but JVM will not be halted.so JVM creates Excpetion object.
if we consider checked exceptions,for example,if we want to load some external file into our program , JVM is responsible for that.so,if any problems are occurred while that file is loading then JVM will be halted .so,then who creates exception object.this is the problem with checked excpetions .
to over come above problem we have to handle checked excptions at compiletime using throws keyword.
if you handle checked exception the following is done
-- JVM executes one by one statement , when it identifies throws keyword followed by checked exception then it creates checked exception object.so,when the exception is occurred then already created exception object is used to print the exception information on the console.
When you can handle the recovery of the state of Object , go for Checked Exception.
When you cannot handle the recovery go for UnCheckedException.
Mostly API developers go for Runtime Exception ,
they do not want to enforce handling exception by the user,
since they themselves do not know how to handle it
Runtime exceptions can occur anywhere in a program, and in a typical one they can be very numerous. Having to add runtime exceptions in every method declaration would reduce a program's clarity. Thus, the compiler does not require that you catch or specify runtime exceptions (although you can).
A possible reason because a NullPointerException is a runtime exception is because every method can throw it, so every method would need to have a "throws NullPointerException", and would be ugly. But this happens with RemoteException.
And a possible reason because RemoteException is not a runtime exception, is to tell it client to treat the exception. But every method in a remote environment need throws it, so there is no difference of throwing NullPointerException.
Speculations? Was I clear?
I won't discuss the decision, I'll just quote the explanation of the decision from Ann Wollrath (who lead the design and implementation of Java RMI). This is extracted from this message from the RMI-USERS archives (message from Jan 1999):
The decision to make RemoteException a
checked exception and requiring remote
methods to list the exception in its
throws clause is not a religious one.
The decision is based on how to make
distributed computing reliable. This
question comes up every once in a
while on our users list. I have a
detailed response that I posted a
while ago. Here it is if you are
interested. I couldn't find it in the
rmi-users archive, so I included it
below.
cheers,
-- Ann
I'd like to address the rationale for
making RemoteException a checked
Exception, rather than a
RuntimeException.
1) networks aren't reliable
I wish that they were, but in fact,
they're not. Every network has
transient failures. You can build in
network redundancy, but the fact is
that most networks don't have that.
Intranets have transient failures, as
does the Internet. So, every RPC made,
is subject to a failure. The types of
failures may not have anything to do
with the "network", per se; if your
server runs out of file descriptors,
your client will get a connect
exception. This isn't a network
failure, in the sense of the network
being broken; your server is in a
transient state of being resource
starved.
RMI is not designed to only handle the
limited case that the whole network
crashes when a single machine crashes.
Such a network would be considered
reliable, either everything is up or
everything is down--there is no
partial failure. RMI is targetted for
a more general audience.
2) RPC failure can't be hidden from
the client
Partial failure is a fact of
distributed programming; these
failures can't be hidden to the
program. A failure shows up in the
client, whether the exception is
checked or unchecked exception, it
still shows up. So, how should such
failures be indicated to the client?
3) checked exceptions foster more
robust programs
There was a time when Oak and the
earliest version of Java did not have
checked exceptions. Exception handling
was advisory, and it was an unsafe
world out there. It was our group (Jim
Waldo and me in particular :-) that
recommended that there be exceptions
checked by the compiler. Jim was quite
persuasive in his arguments, telling
of a world where robust code would
reign. After some consideration, Java
was retooled to have checked
exceptions. Only those exceptions for
which there was no recovery or reflect
application errors would be unchecked
(e.g., OutOfMemoryError,
NullPointerException respectively).
And the world was safe again.
Imagine the Java engineers' surprise
when many exceptions in the Java API
and compiler were changed from
unchecked to checked, and the compiler
enforced the distinction, they
uncovered bugs in the implementations!
So, the best efforts at handling error
conditions, however well intentioned,
was not good enough. That compiler is
useful for something :-)
4) RemoteException should be a checked
exception
Ok, so back on track here. Since a
RemoteException is a fact of life in a
RPC call (see #1, #2) and checked
exceptions force you to write safe
code (#3), we thought that making
RemoteException a checked exception
was a good idea. Writing robust
distributed programs is hard enough,
without having the compiler to help
you with exceptions.
So, some might argue that a
RemoteException is a like an
OutOfMemoryError; your program should
fall over dead if a remote call fails.
I disagree with this point. Yes, in
some cases, there is no recovery from
a RemoteException; but if you are
writing a reliable distributed
program, your client needs to catch
failures and retry appropriately.
Perhaps you need to contact another
server, or abort a transaction of some
sort. If the RemoteException is not
handled, it will percolate up and
crash your client (yuk).
Others have stated that there are some
remote interfaces that are used in
both the local case and the remote
case and the client should not have to
deal with the exceptions in the local
case, so RemoteException should not
have to be in a throws clause and
handling it should not be mandatory.
Now, if we allowed remote interface
methods to omit RemoteException and
had an "rmic" switch to generate stubs
that would throw an unchecked
RemoteException, the client has no
choice in the matter. The decision of
exception handling should remain with
the client. If you define an interface
that only throws unchecked exceptions
you can never write a client that
wants compiler help in dealing with
those exceptions. We have already
seen from the above example that
checked exceptions fosters robust
code.
Another issue that has popped up now
and again is that developers need to
simply translate local interfaces and
use them as remote interfaces. This
may work for a small set of cases, but
if the interface was not designed with
concurrency and partial failure and
call latency in mind, the protocol
captured by the interface may not be
appropriate to use in the distributed
case. Is enough information passed in
those operations to make the
operations idempotent? Perhaps, but
most likely not.
Putting RemoteException in every
throws clause may seem like a pain,
but its the price to pay for writing
robust distributed applications.
-- Ann Wollrath
There is vastly more potential for NullPointerException than RemoteException. Any code that calls a method on an object (meaning practically any Java code at all) could potentially throw a NullPointerException. Only RMI code can throw a RemoteException. This is a tiny subset of "all code."
When writing the RMI libraries, the designers decided to make the client code expect to deal with these exceptions. Considering the nature of remote code execution, I think that's reasonable.
The way I understand it is:
RuntimeExceptions are thrown for things that were preventable.
Exceptions are thrown for things that were unpreventable but recoverable
Errors are thrown for things that were unpreventable and unrecoverable.
For example, NullPointerExceptions can always be avoided and are therefore unchecked exceptions. A RemoteException could occur when there is a network failure, which cannot be reasonably prevented before the method call and therefore is checked.
Besides RemoteException only applying to code from java.rmi and javax.rmi packages (and their subpackages), RemoteException is a type of IOException, much like SocketException is... and all IOExceptions are checked exceptions.