From: Lew on
Mike Schilling wrote:
> It's OK to mention unchecked excpetions in the throws clause, as a
> form of documentation, but it's not required.

It's not helpful, either, so don't do that.

Pretty useless form of documentation, requiring the caller's author to
read the source of the invoked method in order to know about the
unchecked exception. Nor does including an unchecked exception in the
signature force the caller to catch it. So really, don't bother doing
that. Useless is harmful.

If you want to document unchecked exceptions usefully, do so in the
Javadocs. I recommend a combination of '@throws' clauses and verbiage
in the method explanation.

--
Lew

From: Rhino on
Lew <lew(a)lewscanon.com> wrote in
news:e8767322-1d2c-45ab-b9e9-3a242ec74ea4(a)30g2000yqi.googlegroups.com:

> Rhino wrote:
>>> I'm afraid I have some confusion about checked and unchecked
>>> exceptions.
>>
>>> First, am I correct in believing that a checked exception is one in
>>> whic
> h
>>> the method signature contains the throws clause? For example:
>>
>>> � public void myMethod(int foo) throws SuchAndSuchException { }
>>
>>> In other words, is the sole definition of whether an exception is
>>> checke
> d
>>> or unchecked consist of whether it is in a throws clause in the
>>> method signature? Or is there more to recognizing the existence of a
>>> checked exception in existing code?
>>
>
> Jean-Baptiste Nizet wrote:
>> No, you aren't right. Runtime exceptions are exceptions which have
>> RuntimeException as one of their ancestor classes (i.e. which extend
>> RuntimeException or one of its subclasses, or one of its
>> subsubclasses, etc.)
>> Checked exceptions are all the other ones.
>>
>
> ... that extend 'Exception'.
>
>>> Second, the Java Tutorial has a topic on the inappropriate use of
>>> unchec
> ked
>>> exceptions
>>> -http://java.sun.com/docs/books/tutorial/essential/exceptions
> /runtime....
>>> and basically advocates that if a given situation might be
>>> recoverable f
> or
>>> the calling application, a checked exception should be thrown, not
>>> an unchecked one.
>>
>
> That's not exactly true, and is controversial.
>
> My rule of thumb is that unchecked exceptions are for programmer
> mistakes, like 'IllegalArgumentException', and checked exceptions are
> for environmental situations, like 'IOException'. People also use
> unchecked exceptions when they don't want to force client calling code
> to deal with them.
>
> Checked exceptions force calling code to catch them, that's their
> advantage.
>
> Rhino wrote:
>>> I'm revisiting some old classes that I wrote to try to make them as
>>> good
> as
>>> I can and many of the methods in it detect bad input to the methods
>>> and throw IllegalArgumentException. For example, one method examines
>>> a Strin
> g
>>> representation of a year to see if that year is a leap year and
>>> throws IllegalArgumentException if the year portion of the date is
>>> "0000" since there never was a Year Zero. (The year 1 BC was
>>> followed immediately by
> 1
>>> AD).
>>
>>> However, I don't currently have a throws clause in the method
>>> signature
> and
>>> I'm thinking I probably should. Have I got that right?
>>
>
> No.
>
>> You may or may not add the runtime exceptions your method might throw
>> in the throws clause. Usually, they're included in the throws clause
>> in order to be documented by javadoc.
>>
>
> You don't need to put unchecked exceptions in the method signature in
> order to Javadoc them. Just add '@throws <unchecked exception type>'
> to the Javadoc comment.
>
>> Runtime exceptions should be used to signal unrecoverable problems
>> (example : the database is down), or to signal programmer errors.
>> For example, if your method documentation (its contract) says that a
>> given argument must be a string with at least 3 chars, you should use
>> an IllegalArgumentException when it's not the case. If the class
>> documentation (its contract) says that the init method must be called
>> before any other one, you should use an IllegalStateException if it's
>> not the case.
>> But if the job of a method is to parse user-entered value in order to
>> validate it has a given format, it should throw a checked exception
>> if it's not the case, since the caller of your method can't make sure
>> the string is in the valid format before calluing it (it's the
>> method's job in the first place).
>>
>
> "Recoverable" is such a loose term. Most unchecked exceptions are
> recoverable, e.g., if you get 'NullPointerException' you just return
> 'null' or call the method again with a default argument, so it's a
> very useless rule of thumb to say "use runtime or checked for
> [un]recoverable exceptions".
>
> How do you recover from a missing file that is necessary for your
> program? That's signaled by a checked exception ('IOException'), but
> might not fit your definition of "recoverable". OTOH, it is almost
> certainly environmental, not a programmer error, so a checked
> exception makes sense.
>
> Programmers of methods that call methods with checked exceptions often
> pule about what a "bother" it is to have to catch them. Pooh widdoo
> widdoo cwybabies, awwww. API writers (i.e., the methods' authors) put
> checked exceptions in there on purpose, to force calling code to catch
> them and (presumably) to recover from them. If the API writer deems
> such autocracy unnecessary, they'll toss an unchecked exception and
> just let the caller explode without forewarning.
>
> So maybe the rule of thumb is, "If the caller should have prevented
> the exception and you don't want to be bothered with warning them
> because they should have known better, throw an unchecked exception.
> If the caller cannot reasonably be expected to prevent the exception
> by their own diligence, throw a checked exception." It's really up to
> the API writer to choose.
>
So, trying to put this all together, would you agree with this reasoning?

1. In the example I've cited, where the method is going to determine if a
year expressed as a String is a leap year, it is appropriate to throw an
exception (IllegalArgumentException which is a subclass of
RuntimeException) if the year is zero.
2. This situation is recoverable since the user could easily correct this
if it was brought to his attention.
3. IllegalArgumentException should be put in the throws clause of the
message signature.
4. The Javadoc @throws (or @exception) should list
IllegalArgumentException.
5. IllegalArgumentException is RuntimeException since RuntimeException is
its ancestor but IllegalArgumentException is NOT a checked exception
because checked exceptions are never instances of RuntimeException or one
of its descendents.

--
Rhino
From: Lew on
(Please trim your posts.)

Rhino wrote:
> So, trying to put this all together, would you agree with this reasoning?
>
> 1. In the example I've cited, where the method is going to determine if a
> year expressed as a String is a leap year, it is appropriate to throw an
> exception (IllegalArgumentException which is a subclass of
> RuntimeException) if the year is zero.
>

Why do you want to do that? What's special about year zero?

If the Javadocs indicate that year "0" should never be an argument to
the method, then 'IllegalArgumentException' is a good approach, but
otherwise it's not.

Just out of curiosity:
- Why not just use 'GregorianCalendar#isLeapYear(int year)'? FWIW,
that method takes 0 as a legitimate argument, signifying BC 1.

- Are you going to reject dates prior to 1582 in the Catholic world,
1700 in Scandinavia, 1753 in Sweden or 1752 in the former British
Empire?

- Are you aware that New Year's Day was on March 25 prior to the
adoption of the Gregorian calendar? (You would be if you read
Javadocs.)

> 2. This situation is recoverable since the user could easily correct this
> if it was brought to his attention.
>

And therefore ...?

I don't see what being "recoverable" has to do with anything. What
exactly do you mean by "recoverable" anyway?

> 3. IllegalArgumentException should be put in the throws clause of the
> message signature.

No. Bad idea.

> 4. The Javadoc @throws (or @exception) should list
> IllegalArgumentException.
>

If you want that documented, yes. At the very least you'd want that
information in the body of the Javadoc for the method.

However, I don't think I'd consider "0" an illegal argument if it were
I writing the method, which I wouldn't because I'd use
'GregorianCalendar' and not reinvent the wheel.

> 5. IllegalArgumentException is RuntimeException since RuntimeException is
> its ancestor but IllegalArgumentException is NOT a checked exception
> because checked exceptions are never instances of RuntimeException or one
> of its descendents [sic].
>

True by definition.

It's a bad idea to put unchecked exceptions in the 'throws' clause of
a method signature.

--
Lew

From: Rhino on
Lew <lew(a)lewscanon.com> wrote in
news:0376797b-72ab-422d-9985-af8f9585d9be(a)k13g2000yqe.googlegroups.com:

> (Please trim your posts.)
>
Actually, I would but in other threads people have said they're leaving
theirs intact for the benefit of those using Google groups. Won't I be
preventing Google Groups users from benefitting from this discussion if I
trim my posts?

> Rhino wrote:
>> So, trying to put this all together, would you agree with this
>> reasoning?
>>
>> 1. In the example I've cited, where the method is going to determine
>> if a year expressed as a String is a leap year, it is appropriate to
>> throw an exception (IllegalArgumentException which is a subclass of
>> RuntimeException) if the year is zero.
>>
>
> Why do you want to do that? What's special about year zero?
>
As I mentioned in the original post, the year 0 never happened - the
calendar went straight from the year 1 BC to 1 AD. Therefore, if someone
put "0" (or "00" or "000" or "0000") in a form that asked for a year,
they'd be inputting an invalid year.

> If the Javadocs indicate that year "0" should never be an argument to
> the method, then 'IllegalArgumentException' is a good approach, but
> otherwise it's not.
>
> Just out of curiosity:
> - Why not just use 'GregorianCalendar#isLeapYear(int year)'? FWIW,
> that method takes 0 as a legitimate argument, signifying BC 1.
>
Huh? Interpreting 0 as BC 1 makes no sense to me.

> - Are you going to reject dates prior to 1582 in the Catholic world,
> 1700 in Scandinavia, 1753 in Sweden or 1752 in the former British
> Empire?
>
Who said anything about rejecting those dates?

> - Are you aware that New Year's Day was on March 25 prior to the
> adoption of the Gregorian calendar? (You would be if you read
> Javadocs.)
>
Yes, actually I did know that. And I have read Javadocs.

>> 2. This situation is recoverable since the user could easily correct
>> this if it was brought to his attention.
>>
>
> And therefore ...?
>
I'm just trying to lay out my reasoning on the basis of what you and
others have said on this subject to make sure I'm thinking this through
correctly.

> I don't see what being "recoverable" has to do with anything. What
> exactly do you mean by "recoverable" anyway?
>
One of the criteria for whether to make something a checked or unchecked
exception is whether an error is "recoverable", meaning (loosely) that
there is some prospect that the error can be eliminated with a bit of
human intervention. In this case, that human intervention would be
displaying a message to the user saying that the year 0000 is not valid
and please change it to a year that actually existed.

>> 3. IllegalArgumentException should be put in the throws clause of the
>> message signature.
>
> No. Bad idea.
>
Why?

>> 4. The Javadoc @throws (or @exception) should list
>> IllegalArgumentException.
>>
>
> If you want that documented, yes. At the very least you'd want that
> information in the body of the Javadoc for the method.
>
> However, I don't think I'd consider "0" an illegal argument if it were
> I writing the method, which I wouldn't because I'd use
> 'GregorianCalendar' and not reinvent the wheel.
>
If GregorianCalendar is going to interpret the year 0 as the 1 BC without
my telling it to, I'm not sure I want to use GregorianCalendar....

>> 5. IllegalArgumentException is RuntimeException since
>> RuntimeException is its ancestor but IllegalArgumentException is NOT
>> a checked exception because checked exceptions are never instances of
>> RuntimeException or one of its descendents [sic].
>>
>
> True by definition.
>
> It's a bad idea to put unchecked exceptions in the 'throws' clause of
> a method signature.
>
Anyway, the year 0 is not really important here. I'm just trying to
construct an example of what I consider a "recoverable" (for want of a
better word) error so that I can see if I am understanding the use of
checked and unchecked exceptions yet.


--
Rhino
From: Lew on
Lew wrote
>> (Please trim your posts.)
>

Rhino wrote:
> Actually, I would but in other threads people have said they're leaving
> theirs intact for the benefit of those using Google groups. Won't I be
> preventing Google Groups users from benefitting from this discussion if I
> trim my posts?
>

No, quite the contrary. And so what if you did?

Rhino wrote:
> As I mentioned in the original post, the year 0 never happened - the
> calendar went straight from the year 1 BC to 1 AD. Therefore, if someone
> put "0" (or "00" or "000" or "0000") in a form that asked for a year,
> they'd be inputting an invalid year.  
>

The year 1 never happened either. Neither did the year 100. Are you
going to reject those years, too?

Note, again, that the standard Java API does accept the year 0,
because it uses the proleptic Gregorian calendar.

Are you going to reject October 10, 1582? That only happened some
places. Are you going to consider February 28, 1560, to be in the
same year as October 28, 1560? That would be wrong. Do you consider
that Cervantes and Shakespeare died on the same day because they died
on the same date, even though they died ten days apart?

Lew wrote:
>> Just out of curiosity:
>> - Why not just use 'GregorianCalendar#isLeapYear(int year)'?  FWIW,
>> that method takes 0 as a legitimate argument, signifying BC 1.
>

Rhino wrote:
> Huh? Interpreting 0 as BC 1 makes no sense to me.
>

That's because you haven't studied calendars very much, and apparently
haven't bothered to read the Javadocs very much either.

Lew wrote:
>> - Are you going to reject dates prior to 1582 in the Catholic world,
>> 1700 in Scandinavia, 1753 in Sweden or 1752 in the former British
>> Empire?
>

Rhino wrote:
> Who said anything about rejecting those dates?
>

Well, they didn't happen in the Gregorian calendar. Why wouldn't you
reject them?

And am I not permitted to introduce a new concept, or must everything
I suggest have been brought up already before I comment?

Lew wrote:
>> - Are you aware that New Year's Day was on March 25 prior to the
>> adoption of the Gregorian calendar?  (You would be if you read
>> Javadocs.)
>

Rhino wrote:
> Yes, actually I did know that. And I have read Javadocs.  
>

Then you already knew about the proleptic Gregorian calendar and that
the Java 'GregorianCalendar' accepts year 0.

Rhino wrote:
>>> 2. This situation is recoverable since the user could easily correct
>>> this if it was brought to his attention.
>

Lew wrote:
>> And therefore ...?
>

Rhino wrote:
> I'm just trying to lay out my reasoning on the basis of what you and
> others have said on this subject to make sure I'm thinking this through
> correctly.
>

Well, I pointed out that "recoverable" was not relevant, as it is far
too loose a concept that can apply to both checked and unchecked
exceptions, and therefore does not distinguish when to use one or the
other.

Lew wrote:
>> I don't see what being "recoverable" has to do with anything.  What
>> exactly do you mean by "recoverable" anyway?
>

Rhino wrote:
> One of the criteria for whether to make something a checked or unchecked
> exception is whether an error is "recoverable", meaning (loosely) that
>

No, it isn't.

> there is some prospect that the error can be eliminated with a bit of
> human intervention. In this case, that human intervention would be
> displaying a message to the user saying that the year 0000 is not valid
> and please change it to a year that actually existed.
>

That reasoning applies equally well to checked or unchecked
exceptions.

Rhino wrote:
>>> 3. IllegalArgumentException should be put in the throws clause of the
>>> message signature.
>

Lew wrote:
>> No.  Bad idea.
>

Rhino wrote:
> Why?
>

As I have said a couple of times already in this thread, and surely
you have read, because it accomplishes nothing. It does not add to
the documentation, it does not become part of the method signature, it
does not require callers to catch the exception, and it's a waste of
time and effort. The 'throws' clause is designed for and only useful
with checked exceptions.

Instead, as you wrote:
>>> 4. The Javadoc @throws (or @exception) should list
>>> IllegalArgumentException.
>

Rhino wrote:
> If GregorianCalendar is going to interpret the year 0 as the 1 BC without
> my telling it to, I'm not sure I want to use GregorianCalendar....
>

But that is correct behavior, by ISO standard 8601. You really need
to study up on calendars, particularly the Gregorian calendar. May I
suggest careful study of
<http://en.wikipedia.org/wiki/Gregorian_calendar>
particularly
<http://en.wikipedia.org/wiki/
Gregorian_calendar#Proleptic_Gregorian_calendar>
?

Sometimes people, and APIs, do the right thing even if you don't tell
them to. Furthermore, it is not your job to tell the standard API
what to do, but the standard API's job to tell you what it actually
does. As long as it works as documented, then you have no legitimate
gripe.

Rhino wrote:
> Anyway, the year 0 is not really important here. I'm just trying to
> construct an example of what I consider a "recoverable" (for want of a
> better word) error so that I can see if I am understanding the use of
> checked and unchecked exceptions yet.
>

"Recoverable" is an awful, terrible, vague, useless, unworthy and
ridiculous criterion for choosing between the two. Instead, consider
either
- RuntimeException for programmer error, checked exception for
environmental error, or
- RuntimeException to let a caller slide without a 'catch' clause,
checked exception to force the 'catch'.

Whatever criterion you use, it's going to be a matter of style. There
are entire APIs out there that refuse to throw checked exceptions by
dint of the API writers' philosophy, others that go hog-wild with
them. It's up to the API writer what they choose to impose.

--
Lew