2016-09-22 5 views
1

Pourquoi ByteArrayOutputStream. close est déclaré avec throws IOException? D'abord, de facto, il ne peut rien lancer, car son corps est vide. Deuxièmement, de jure, il ne peut rien lancer, car sa documentation dit "fermer un ByteArrayOutputStream n'a aucun effet".Pourquoi ByteArrayOutputStream.close() throws IOException?

N'est-ce pas une erreur (non importante, mais quand même)?

Oui, je comprends que sa superclasse implémente OutputStreamClosable, la méthode close qui est autorisé à jeter IOException. Mais personne n'interdit de l'ignorer (dans ByteArrayOutputStream) avec la méthode close sans spécification de projection. (Même si la suppression d'un méthode plus-lancer avec une méthode moins jeter était interdit dans certaines versions anciennes de Java, en changeant ByteArrayOutputStream. close définition maintenant ne sera pas le changement incompatible.)

+2

si la définition a été modifiée, les codes existants dont la prise IOException va se compiler erreur bloc catch 'Inaccessible pour IOException. Cette exception n'est jamais levée depuis le corps de l'instruction try. – saka1029

+0

@ saka1029: Je pense que vous êtes sur la bonne voie. – Holger

+0

@ saka1029, vous avez raison (je pensais que cela causerait un avertissement, pas une erreur). – Sasha

Répondre

2

L'explication la plus plausible (en plus surveillance) est la compatibilité. Retour en Java 1.1, ByteArrayOutputStreamdid not override close(), donc il a hérité de la méthode de OutputStream qui déclare IOException. À l'époque, cela aurait pu être un oubli. Peut-être, les développeurs ont pensé que c'est inutile, car personne ne va appeler close() sur un ByteArrayOutputStream de toute façon. Mais la documentation manque d'une déclaration explicite sur l'appel close() étant inutile. Depuis Java 1.2 aka Java 2, ByteArrayOutputStreamdoes override close(). Cependant, si vous supprimez la clause throws, le code appelant close() sur un ByteArrayOutputStream est intercepté et le code IOException est coché pour générer une erreur de compilation lorsque l'exception n'est pas renvoyée à un autre emplacement dans le bloc try. Comme cela n'affecte pas la compatibilité binaire, cela peut sembler étrange compte tenu de la quantité de changements avec plus d'impact sur le niveau du code source depuis lors.

Mais cette décision a été prise depuis longtemps. On ne sait pas non plus pourquoi le remplacement a été ajouté du tout, car la no-op héritée était suffisante et le remplacement ne change pas la signature et ne contient pas non plus d'amélioration de documentation utile dans cette version, aucune clarification sur close() . L'explication la plus plausible est qu'elle a été ajoutée avec l'intention de supprimer la clause throws, mais il a été détecté que l'incompatibilité était un problème avec certains codes existants.

En fin de compte, il n'est pas vraiment important de l'enlever. Si votre type de compilation est ByteArrayOutputStream, vous savez que vous n'avez pas besoin d'appeler close(). Dans tous les autres cas, à savoir si le type de compilation est plus générale OutputStream, vous devez close() et gérer la déclaration IOException ...

+0

Je comprends, que ce n'est pas vraiment important de l'enlever. – Sasha

+0

En fait, la partie principale de la réponse a été introduite par @ saka1029: Je ne savais pas que * supprimer * une clause throws peut vraiment introduire des incompatibilités. Je pense que ce fait (que la suppression d'une clause throws peut introduire des incompatibilités avec les sources, que "Inaccessible catch block for ..." est une erreur, pas un avertissement) est une erreur en soi. – Sasha

+0

@ La déclaration de saka1029 est un commentaire (pas une réponse), donc je ne peux pas l'accepter (bien qu'elle soit apparue en premier et qu'elle soit laconique, alors j'aimerais beaucoup le faire). – Sasha