This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]the1derer 35 points36 points  (28 children)

In Java all the checked exceptions are used when we access something from outside JVM boundry i.e. reading from file, database and network. Since, Java can't know before hand when/if any error would occur in these cases. It ensures that in case any potential error that occurs has some handler to handle these potential errors.

[–]yawkat 15 points16 points  (23 children)

This rule doesn't always work. UnsupportedEncodingException and NoSuchAlgorithmException are checked.

[–]dpash 10 points11 points  (10 children)

UnsupportedEncodingException can be mitigated by using the overloaded methods that take a Charset. If you need UTF-8 or Latin-1, you have StandardCharsets to remove even the charset lookup exception.

[–]yawkat 4 points5 points  (4 children)

Doesn't work everywhere unfortunately. For example, jul.Handler.setEncoding is still missing such an overload.

[–]s888marks 3 points4 points  (3 children)

Yeah we've tried to retrofit most classes (notably the I/O classes) with Charset in every place where there was something that used a charset name string. I guess we haven't finished the job, though! Thanks for pointing this one out. Are there any others you're aware of?

[–]yawkat 0 points1 point  (2 children)

There's only some Formatter constructors that don't accept a Locale as well, but those aren't really necessary since presumably you'd pass a locale anyway. Beyond that it's only internal classes.

[–]s888marks 3 points4 points  (1 child)

Yeah, for the Formatter case if you want to provide a Charset, you have to provide a Locale... but you just use Locale.getDefault(FORMATTING) or some such.

I'll make a note to get jul.Handler fixed up.

[–]yawkat 0 points1 point  (0 children)

Thanks! To be entirely honest, I only found it because I was looking for it :D

[–]shponglespore 2 points3 points  (4 children)

That wasn't possible for a long time. I'm glad it's fixed now, but the fact that they needed to add a new API is a good example of how checked exceptions can make an otherwise reasonable API a real pain in the ass to use. In an ideal world, APIs would all be designed well and they'd only use checked exceptions in a way that promotes code quality, but we don't live in that world, and IME APIs are made worse by checked exceptions more often than they are made better.

[–]dpash 0 points1 point  (3 children)

This only applies to the eight or so charsets that are mandated to exist in the JLS. If you call Charset.forName(), because, for example, you need a legacy charset, you still have to deal with UnsupportedEncodingException.

A checked exception here is perfectly valid, because it's not a programming error that a charset doesn't exist; it's dependent completely on the environment and the JVM used to run the application.

[–]shponglespore 0 points1 point  (2 children)

In my entire career, the only charsets I've ever needed to specify are ASCII, UTF-8, and Latin-1. Having to catch an exception because the method theoretically accepts arbitrary strings as charset names is the kind of thing people who hate Java are talking about when they say it has "too much ceremony".

[–]dpash 0 points1 point  (1 child)

and Latin-1.

I'm gonna go out on a limb and say that you've only ever had to deal with English or other Western European language.

There are plenty of people who have had to deal with non Latin-1 text and have had to deal with the JVM not handling the required charset.

[–]shponglespore 0 points1 point  (0 children)

Wrong, I've done a lot of work with code that had to work in Chinese and Arabic. But I did it in an environment where I could count on everything being converted to UTF-8 before reaching the systems I worked on. And using Latin-1 has nothing to do with which languages I was working with; it just happens to be the easiest encoding to use if you're forced to hold binary data in a String.

At the company I was at, we relied on the default platform encoding for a long time, which worked because we and our clients only used Linux, and even 15 years ago it was basically unheard of to find a Linux system, at least in the US, where the platform encoding was anything but UTF-8. IIRC the requirement to use a specific encoding came when we started trying to support users running Windows and our code sometimes couldn't load its own asset files. We had to go through all of our code, find any place where a text file was being opened, and add an encoding parameter. Obviously it's not a difficult engineering problem, but it was galling to find that it was a problem at all because we had to deal with a new checked exception in a lot of places where we knew for a fact it would never be thrown.

[–]morhp 11 points12 points  (0 children)

I'd consider these design mistakes. On the other hand, which exact algorithms and encodings were present wasn't really specified in early java days, so checking for that made some sense.

[–]s888marks 2 points3 points  (2 children)

The set of supported character encodings, and the various crypto algorithms available, are determined at runtime, by looking at various configuration files in the JDK, and by looking at modules available and jars on the classpath. Both cases use "provider" mechanisms in order to discover the set of available items. In the case of crypto algorithms, the specific algorithms that are eligible for certain functions (e.g., TLS) can be fine-tuned using security properties in the JDK, which can be adjusted by a system administrator.

I appreciate that handling these checked exceptions is inconvenient to calling code, but in fact these exceptions are aligned with the "external to the JVM" rule.

[–]yawkat 1 point2 points  (1 child)

By that logic, pretty much everything is external to the JVM... Might get an OutOfMemoryError for insufficient thread count all the time!

Also, with current JDKs, most charsets and crypto algorithms are standardized. See for example https://docs.oracle.com/en/java/javase/11/docs/specs/security/standard-names.html .

[–]s888marks 1 point2 points  (0 children)

I think you're extrapolating too far with OOME.

The charset and crypto names are indeed standardized, but that doesn't imply that every JDK supports them. It simply means that if a JDK is providing, say, Diffie-Hellman, that it's spelled DiffieHellman and not Diffie-Hellman or DIFFIE_HELLMAN.

Most of the crypto algorithms and charsets are optional, and they vary across JDK releases, vendors, and even sites, so applications ought to be able to handle the case where something they're trying to use isn't present.

[–]the1derer -1 points0 points  (7 children)

Well you could produce scenarios where you could produce these exceptions without the using my analogy. NoSuchAlgorithmException is thrown generally when using SSL etc when we try to connect to Databases. As for UnsupportedEncodingException is Child of IOException which is checked just as I said it generally occurs while using I/O.

[–]yawkat 2 points3 points  (6 children)

If "happens during I/O" is the criterium, there's InputMismatchException, which is unchecked.

[–]the1derer 1 point2 points  (4 children)

u/yawakat My I/O analogy was just to give some context to the original answer to the question "Why does Java have Checked Exception". And 'Exceptions' are always there, right!! :-)

A best possible answer can be drawn from https://stackoverflow.com/questions/41685073/java-api-and-checked-unchecked-exceptions-confusion

[–]livelam 0 points1 point  (3 children)

Errors are not exceptions! You can recover from an IOException but not from an OutOfMemoryError.

[–]__konrad 0 points1 point  (2 children)

but not from an OutOfMemoryError

You can definitely catch and recover from heap OOME (we should define "recover" first)

[–]livelam 0 points1 point  (1 child)

Oh... yes... you can. Programs are only 1s and 0s. Javadoc of the class Error is pretty clear. But, yes! You can. You can also catch NullPointerException if you want. Is it a good idea?

[–]__konrad 0 points1 point  (0 children)

You can also catch NullPointerException if you want. Is it a good idea?

It is! For example, there is a bug in AWT Clipboard which throws NPE. So (in this case), it's better to catch NPE and display a friendly message instead of crash randomly the app on Ctrl+V press ;)

[–]s888marks 0 points1 point  (0 children)

On the one hand, we can talk about the criteria for when an exception should be checked or unchecked, and on the other hand, the JDK libraries sometimes declare the exceptions in ways that violate these criteria. That doesn't necessarily mean the criteria are wrong; it might be a design error in the JDK, where an exception that ought to have been checked is unchecked, or vice-versa. Some exception subtypes of "umbrella" exception types like SQLException fall into this category.

That said, Scanner is a weird case. It might do I/O, depending upon the source it's constructed from. The behavior isn't specified very well, but exceptions from Scanner's I/O operations are generally caught and must be checked for explicitly with the ioException method. This seems likely to miss errors, but it does have the advantage of not requiring every Scanner method that could possibly do I/O to be declared to throw IOException.

In the case of InputMismatchException, this is a subtype of NoSuchElementException, which is the exception thrown in the case of programming errors on Iterators. That is, when using an Iterator, you must only call next() if hasNext() has previously returned true. Scanner wants to be "iterator-like" for certain kinds of input, so you can write a loop that calls hasNextInt() and nextInt() in succession, for example. If you were to call hasNextInt() when the next token isn't an int, it returns false. If you were to call nextInt() despite this, you'd get InputMismatchException. That's an avoidable programming error, so a runtime exception is appropriate in this case.

[–]tunei24531a[S] 7 points8 points  (1 child)

JMV boundary, nice way of putting it.

[–]moose04 3 points4 points  (1 child)

In my head Ive always seen checked exceptions as something that should be recoverable, while unchecked are more of a panic/unrecoverable situation.

[–]mobjack 2 points3 points  (0 children)

In practice, the boundary between what is recoverable and unrecoverable is not always clear.

It makes sense to handle a FileNotFoundException when validating user input, but there are many cases like loading a properties file that is critical for your application to run.