How is exception handling implemented in higher-level programming languages (like Java)? By this, I don't mean how to use exceptions within a language; I mean how the compiler generates code (assembly, or some intermediate, like Java byte code) that we recognize as exception-handling, because in the end, the computer can execute only instructions; Everything of a higher-level must be comprised of those instructions.
In C, before exceptions existed, you would return an error code, but if a function already returns something, then what? Perhaps return a structure of both the error code and the real result?
The compiler outputs an athrow instruction (JVM Specification) at the throw site, and an Exceptions attribute (#4.7.5) in the code of the method that shows where all the various catch clauses are, what range of instructions they cover, and what exception types they catch.
Related
For example:
FileOutputStream("file")
would compile in Kotlin, but in Java it would give a compiler error. Why?
Kotlin does away with Java's checked exceptions. Exceptions checked at compile time and declared in method signatures, though familiar to Java developers, are widely considered a failed experiment outside and to some degree inside the Java community.
So Kotlin did away with them, and with some of the boilerplate associated with using resources (like FileOutputStream) with the .use method shorthand for Java 7's try-with-resources.
It can be difficult to answer without letting some opinions interfere. I will just say that Kotlin is aimed at large software projects and give you what the Kotlin team claims regarding checked exceptions (from https://kotlinlang.org/docs/reference/exceptions.html):
Checked Exceptions
Kotlin does not have checked exceptions. There are many reasons for
this, but we will provide a simple example.
The following is an example interface of the JDK implemented by
StringBuilder class:
Appendable append(CharSequence csq) throws IOException; What does this
signature say? It says that every time I append a string to something
(a StringBuilder, some kind of a log, a console, etc.) I have to catch
those IOExceptions. Why? Because it might be performing IO (Writer
also implements Appendable)… So it results into this kind of code all
over the place:
try {
log.append(message)
}
catch (IOException e) {
// Must be safe
}
And this is no good, see Effective Java, Item 65: Don't ignore
exceptions.
Bruce Eckel says in Does Java need Checked Exceptions?:
Examination of small programs leads to the conclusion that requiring
exception specifications could both enhance developer productivity and
enhance code quality, but experience with large software projects
suggests a different result – decreased productivity and little or no
increase in code quality.
Other citations of this sort:
Java's checked exceptions were a mistake (Rod Waldhoff)
The Trouble with Checked Exceptions (Anders Hejlsberg)
I usually tend NOT TO catch "Exception", but only the exceptions i expect methods to throw, i hear often that is good practice.
But today i came across this issue, an IllegalArgumentException thown by the method URLDecoder.decode(string,encoding).
This method is declared as:
public static String decode(String s, String enc)
throws UnsupportedEncodingException{.....
But it then ('if you look at the source') throws IllegalArgumentException in three different places.
So my question to more experienced programmers is, shall i catch "Exception"? or is this method just been declared wrongly?
Thank you
No you should not catch those exceptions. IllegalArgumentException means a precondition has failed. It's usually caused by a bug in your program, and should crash your application. If the input came from the user, detect the wrong input and show a significant message.
If you have an exception handling policy in your application, then you could let this exception bubble out.
There are two main types of Exceptions in Java, ones that are declared (eg UnsupportedEncodingException) and Runtime exceptions which you do not have to catch (eg IllegalArgumentException). However, if you do not catch the Runtime exception it will crash your thread and potentially your whole application, so it depends on your use case. When I am building big applications with several threads and doing several things at once, when I call 'unpredictable' methods like 'decode' (especially anything that takes in user input, or reads from files that I am not in charge of, etc) I like to catch Exception, so that I can log a nice clean error or return a meaningful error to the user, but the rest of my application carries on running normally. But if I am writing a single-threaded application where you run it, provide some input, and it gives some output, I would not bother catching Runtime exceptions as the output and stacktrace will be printed to the console and I can see exactly what the problem is - and it doesn't matter that the application died because I can fix the problem and run it again.
Just my personal preference - hope that helps!
exists two kinds of exceptions in Java, checked and unchecked exceptions, here are the differences:
Unchecked exceptions: they have RuntimeException in its inheritance tree. The compiler doesn´t requires you to catch'em explicitly.
Checked exceptions: They don´t have RuntimeException in its inheritance tree. You have to catch'em in a try-catch block of declare in a throws clausule.
Basically according to all development methodologies, your code have to be tested, you have to cover all scenarios where unchecked exceptions could occur, because they are generated by errors in your logic code or bad usage of API and you have to correct them. That's why in the final code they should never be catched, because they should never happen.
In the other hand the checked exceptions could happen by causes not related to your code logic i.e. Network loose, Changes in the filesystem priviledges, etc. So you should prepare you code to be ready and catch or delegate the exception.
I hope it helps. And sorry for my english
If you take a look at the source of decode(String s, String enc) you will see three places where an IllegalArgumentException is throw:
"Illegal hex characters in escape (%) pattern - negative value"
"Incomplete trailing escape (%) pattern"
"Illegal hex characters in escape (%) pattern -"
All three errors are not usage errors but real errors in the input. So it is correct that IllegalArgumentException is not a checked exception.
It is correct that UnsupportedEncodingException is a checked exception. The caller could handle it.
To answer your question: Be as specific as possible in what you catch. Don't just catch Exception because you will have no easy way to decide how to proceed. You could could catch both UnsupportedEncodingException and IllegalArgumentException in different catch blocks. You must catch UnsupportedEncodingException.
I'm learning to use java, I think I already know the basics of C++. But, as I just started learning java, the first bits of 'hello world' program I noticed uses 'throws exception' when initiating the main function in the main class. Why is it used? Do we do something similar in c++? Is returning 0 in int type main function in c++ a similar thing?
In Java, specifying that a methodthrows SomeException means that any method calling that method will have to either catch or itself throw that exception. In the case of the main function, it just means that you don't have to catch any exceptions that may occur directly in the main method, they will instead be passed on to the underlying runtime, resulting in a stack trace print and program exit.
It isn't, or at least, I've never seen a main in Java which
did it. I'm not even sure that it's legal. (Given the way Java
uses exceptions, it shouldn't be. Only RuntimeException and
Error should propagate out of main.)
Java tends to overuse exceptions; especially, it uses exceptions
in cases where return values would be more appropriate (e.g.
things like not being able to open a file). In a correct
program, these exceptions must be handled (just as in a correct
program, C++ returned error codes, or in the case of input and
output, the stream state, must be handled). Java uses the
exception specifier to declare these exceptions (and only
these—it isn't necessary to declare things that would be
an exception in C++).
I heard from some people that in Scala we tend (like other functional languages) to not break the control flow... Instead by convention we return the error in an Either Left.
But how do we get the stracktrace from that exception?
For now i return in the Left a simple Error case class with a code, message and cause (Error too). But if i have an error, i can't get the stacktrace.
If my application become complexe it may be hard to find the code block that returned that Error... The root cause is essential.
So what do we do in practice?
Should i return, instead of a custom Error, the java type Exception or Throwable in my Left?
What's the best practice for Scala exception handling without loosing important informations such as the stacktrace and the cause?
I'd suggest using Either[java.lang.Throwable, A] (where Throwable still gives you access to the stack trace), and (in general) making your custom error types extend java.lang.Exception.
This is the practice used by Dispatch 0.9, for example, where Either[Throwable, A] is used to represent computations that may fail, and the custom error types look like this:
case class StatusCode(code: Int)
extends Exception("Unexpected response status: %d".format(code))
Scalaz 7's Validation.fromTryCatch(a: => T) also returns a Validation[Throwable, T], where Validation is roughly equivalent to Either.
I have a quick question about dealing with exceptions being thrown by libraries under JNA...
When I throw an exception in the underlying native code, JNA gets a invalid memory access error. I'm assuming this is because C libraries cannot throw an exception up through it's stack (it's actually C++/CLR but has C exports)? So is there no real way to report the exception to Java? Or "should it work" and I'm just doing something incredibly wrong?
DllExport void Initialize(char* dir)
{
throw gcnew System::Exception("Testing");
}
It would be nice for Java to be able to detect these thrown exceptions, and I guess I could actually look into passing a memory pointer into all my C exports and check to see if those are null or not, but seems like a roundabout way.
C++ exceptions can only be handled in C++ code. They should never be allowed to escape the C++ world (i.e., a C interface of C++ code should never let exceptions propagate). It is not even safe to let a C++ exception propagate through a layer of C code between two C++ modules (e.g., when a C++ function calls a C function which in turn calls a C++ function).
One of the reasons for this is that there is no standard on how C++ exceptions should be implemented, so C++ modules are only binary-compatible if compiled by the same compiler (in the same version). So code in any other language can't be set up to handle C++ exceptions.
In this case (C++ library, C interface, called from Java) you would have to catch the C++ exception, propagate the information through the C interface (e.g., by using error return codes), check for it in Java and throw an exception there.
You need to handle the c++ exception yourself and instead build a java exception which can be passed to the java side of the code.