Proposal: Infer checked exceptions from private methods
Brian Goetz
brian.goetz at oracle.com
Thu Mar 3 21:36:44 UTC 2022
While I understand the motivation for such a request, I suspect it would
likely make things worse, not better.
When we did type inference for local variables, we deliberately
restricted it to local variables only, not fields or methods, because
methods and fields are part of a classes API, and we wouldn't want the
API to subtly change based on implementation detail, which would cause
linkage errors.
Clever folks observed: "but AHA, you could use inference for *private*
method returns and fields without having that problem, why wouldn't you
do that?"
And we did have a reason for that: simplicity. By not coupling
inference to complex other details such as accessibility, it is easier
to reason about when inference can be used (developers hate when they
can't easily understand which features can be used where), and more
importantly, means that making a private method public is simply a
matter of changing the accessibility, not rewriting the method header.
Ad-hoc interactions between features (e.g., inference and accessibility)
is a pernicious form of hidden complexity.
Supporting inference of exceptions here is very similar to inference of
return type.
Such a feature is also likely to be misinterpreted; not all developers
will immediately realize this is mere inference, they may well think it
is "turning off checked exceptions" (and many of them will want to
believe this.) Which, for the vocal segment of Java users who think
checked exceptions are the worst thing ever, would seem like a big slap
in the face -- "you let me turn off checked exceptions, but only in the
least important places!"
On 3/3/2022 8:08 AM, negora wrote:
> Hi:
>
> I've seen many programmers propagate all checked exceptions up the
> call stack,
> from multiple private methods to the first non-private method of the
> class.
> There, some exceptions are allowed to propagate, whereas others are
> wrapped
> with one or more unchecked exceptions.
>
> So I would like to propose a variation of the `throws` clause, such as
> `throws
> uncaught` or `throws *`, so that the compiler infers which checked
> exceptions
> are thrown. **This feature would be limited to private methods,** so that
> developers are forced to think about their public APIs and don't let
> implementation details leak.
>
> Thanks to this, propagating exceptions inside a class would be super
> easy and
> would not clutter the code so much. I work in big server applications
> and some
> times the list of exceptions to "carry" between private methods is so
> long,
> that even the simplest method takes multiple lines of code, making it
> hard to
> read.
>
> In addition to this, if you changed the implementation in the future,
> you would
> have not to worry much about the exceptions thrown by the private
> methods,
> because you could make the necessary changes only in the non-private
> methods.
>
> Example with irrelevant parts omitted:
>
> ```
> /* This method does nothing special. */
> public void addStudentToRepository (
> String name,
> String surname
> Integer schoolID)
> throws SchoolNotFoundException {
>
> try {
>
> ...
> School school = findSchool (schoolID);
> ...
>
> } catch (UnavailableRepositoryException | WrongIDTypeException ex) {
> throw new ImplementationException (ex);
> }
>
> }
>
> /* Here is the interesting part. */
> private School findSchool (Integer id)
> throws uncaught {
> /* ^^^ This is equivalent to throw
> * "UnavailableRepositoryException",
> * "WrongIDTypeException",
> * and "SchoolNotFoundException" separately.
> */
>
> School school = repository.findObject (id, School.class);
> /* ^^^ This throws
> * "UnavailableRepositoryException"
> * and "WrongIDTypeException".
> */
> if (school != null) {
> return school;
> } else {
> throw new SchoolNotFoundException (id);
> }
>
> }
> ```
>
> This example is very basic. I know that
> `UnavailableRepositoryException` and
> `WrongIDTypeException` could inherit from a common
> `RepositoryException`, but:
>
> 1. You lose the specific types of the exceptions.
>
> 1. Sometimes that's not an option, because the exceptions come from
> different
> libraries or frameworks.
>
> Thank you!
>
> Best regards,
> negora.
More information about the amber-dev
mailing list