CONNEXION
  • RetourJeux
    • Sorties
    • Hit Parade
    • Les + populaires
    • Les + attendus
    • Soluces
    • Tous les Jeux
    • Gaming
  • RetourActu Gaming
    • News
    • Astuces
    • Tests
    • Previews
    • Toute l'actu gaming
  • RetourBons plans
    • Bons plans
    • Bons plans Smartphone
    • Bons plans Hardware
    • Bons plans Image et Son
    • Bons plans Amazon
    • Bons plans Cdiscount
    • Bons plans Decathlon
    • Bons plans Fnac
    • Tous les Bons plans
  • RetourJVTech
    • Actus High-Tech
    • Intelligence Artificielle
    • Smartphones
    • Mobilité urbaine
    • Hardware
    • Image et son
    • Tutoriels
    • Tests produits High-Tech
    • Guides d'achat High-Tech
    • JVTech
  • RetourCulture
    • Actus Culture
    • Culture
  • RetourVidéos
    • A la une
    • Gaming Live
    • Vidéos Tests
    • Vidéos Previews
    • Gameplay
    • Trailers
    • Chroniques
    • Replay Web TV
    • Toutes les vidéos
  • RetourForums
    • Hardware PC
    • PS5
    • Switch 2
    • Xbox Series
    • Switch
    • Pokemon pocket
    • FC 25 Ultimate Team
    • League of Legends
    • Tous les Forums
  • PC
  • PS5
  • Xbox Series
  • Switch 2
  • PS4
  • One
  • Switch
  • iOS
  • Android
  • MMO
  • RPG
  • FPS
En ce moment Genshin Impact Valhalla Breath of the wild Animal Crossing GTA 5 Red dead 2
Liste des sujets

[java] exception dans un constructeur

godrik
godrik
Niveau 30
15 juillet 2020 à 21:10:05

Yo les gens,

J'ai un constructeur qui ressemble a ca:


class AC {
  public AC(int a) {...}
  public AC(String s) { this (complexThrowerReturningAnInt(s));}
}

Mon probleme est que complexThrowerReturningAnInt peut envoyer une ExceptionALaCon. Je voudrais recaster l'exception dans quelquechose de plus comprehensible pour l'utilisateur comme une FileFormatException. Pour l'instant j'ai:

public AC(String s) throws ExceptionALaCon { this (complexThrowerReturningAnInt(s));}

Je voudrais recoder l'exception en autre chose. Moralement faire:

public AC(String s) throws FileFormatException { 
  try{
    this (complexThrowerReturningAnInt(s));
  } catch (ExceptionALaCon ealc) {
    throw FileFormatException("not a correct whateever format", ealc);
  }
}

Naturellement java m'envoye chier parceque tu ne la ligne "this" doit etre la premiere ligne de la fonction. Et evidement attraper l'exception du constructeur laisse potentiellement l'objet dans un etat partiellement construit donc il m'aime pas.

Est ce qu'il y a une syntaxe pour recaster une exception dans un constructeur en java ou est ce qu'il faut hacker comme un mal propre? Est ce qu'il y a un equivalent des function-try-block de C++? ( https://en.cppreference.com/w/cpp/language/function-try-block )

Coin!!

_S0uL
_S0uL
Niveau 9
15 juillet 2020 à 21:45:42

La solution que je vois, mais je suppose que tu cherche peut être quelque chose de plus propre, c'est celle là :

public AC(String s) throws FileFormatException { 
  this(null); // ou this(0);
  try{
    this.a = complexThrowerReturningAnInt(s);
  } catch (ExceptionALaCon ealc) {
    throw FileFormatException("not a correct whateever format", ealc);
  }
}

Le soucis c'est que si tu as du traitement autre qu'un assignment de variable dans le constructeur que tu overload, tu devra dupliquer ton code ou mettre le tout dans une méthode statique.

Dans un cas aussi simple ça ne sert clairement pas à grand chose de faire appel à this(0) mais si tu as d'autres paramètres, ça peut avoir du sens d'initialiser ceux là via l'autre constructeur et seulement a avec ce constructeur là.

Par contre si tu as d'autres variables qui dépendent de a dans le premier constructeur, c'est clairement une mauvaise solution.

HosterThePepe
HosterThePepe
Niveau 6
15 juillet 2020 à 21:53:38

Comme la proposé mon vdd tu peux faire une fonction statique qui encapsule l'appel de ton constructeur (que tu passerais en privée ?) avec un try catch.

godrik
godrik
Niveau 30
15 juillet 2020 à 22:04:08

_Soul, en l'occurence, l'appel a this() est vachement complique. J'ai fait simple avec un int pour l'exemple. Mais en fait, je passe pas un int, je passe un objet en cours de de-serialization.

HosterThePepe, moralement la semantique expose par l'objet devrait etre la semantique d'un constructeur qui envoye une exception. Encapsuler ca dans une autre fonction fait parti des truc hack-y que je ne prefererais pas faire. C++, a des function-try-block depuis une eternite pour regler ce genre de probleme simplement. Je me demandais si il y avait une notation facil en java pour faire la meme chose.

J'imagine que non, java est vraiment un langage specifie mochement...

_S0uL
_S0uL
Niveau 9
15 juillet 2020 à 22:19:34

Oui je me doutais bien que ça serai plus compliqué que ça sinon pas vraiment d'intérêt. Malheureusement, il n'y a pas l'air d'exister quelque chose pour ce genre de cas en Java.

Et est-ce que tu ne pourrai pas t'en sortir en créant une factory de cette classe qui s'occuperait de faire le traitement avant l'appel à ton premier constructeur ? Là c'est vraiment de la spéculation, je ne sais pas si ton implémentation permettrait de faire ça.

godrik
godrik
Niveau 30
15 juillet 2020 à 22:25:07

C'est ce dont j'avais peur. En l'occurence, je vais certainmer wrapper complexThrowerReturningAnInt dans autre chose pour changer la throws-specification. Il fautque j'en fasse 3 ou 4 comme ca, mais ca devrait marcher.

infireman
infireman
Niveau 9
16 juillet 2020 à 12:39:31

Les exceptions rendent le flot de controle hasardeux en plus de coûter en performance, il ne faut pas les utilise

godrik
godrik
Niveau 30
16 juillet 2020 à 16:51:36

infireman, merci de l'avertissement. Cependant, autant c'est vrai dans les cas generaux, ca ne l'est pas forcement dans les cas particulier.

Pour commencer, si la performance etait une contrainte principale de mon application, probablement, je ne l'ecrirais pas en Java.

Mais de facon general, aucune application n'est ecrite avec un seul but. Il y a toujours un compromis entre fonctionallite, maintenance, cout de developpement, et performance. (Et plein d'autre chose certainement.) En l'occurence le code ou mon probleme apparait est dans le sous systeme d'IO de mon application. Les systemes d'IO sont lent pour commencer. Au plus bas mots, tu payes une latence disque, sans meme compter le nombre de context switch a chaque fois qu'il faut retomber en espace noyaux pour lire le bout de donnee qui suit. L'overhead du handler d'exception est relativement faible en comparaison.

Aussi, les flots de controles hasardeux ne sont un probleme que pour des applications mal ecrite. En C++ par exemple, adherer aux principes RAII rends les codes plus facile a lire en presence d'exception que les codes equivalent sans exceptions. Ca diminue significativement le nombre de branchement de code qui servent a gerer les cas exceptionnel et la maintenabilite du code augmente. De toute facon si ce sont des questions particulierement importantes, on utilisera des fuzzers et des outils de couverture de code pour s'assurer d'avoir des tests complets.

Dans les codes orientes objets, les exceptions permettent d'assurer que si l'objet est construit, alors il est construit correctement. Je peux utiliser l'objet sans avoir a me demander avant chaque utilisation que l'objet et les fonctions que j'utilise de l'objet sont semantiquement correctes. Des semantiques simples rendent la programmation beaucoup plus abordable a des developpeurs moins experimente. Ca permet de laisser les codes simples a ecrire a des developpeur juniors qui ont juste besoin d'etre relu et valide par un developpeur experimente.

En bref, si je perd 5% de performance (que je ne suis pas sur qu'on perd avec des exceptions en general) et que je gagne 3 ordres de magnitude en programmabilite et maintenance, j'appelle pas ca un probleme, j'appelle ca une opportunite.

Sous forums
  • Aide à l'achat Mac
  • Création de sites web
  • Internet
  • Macintosh
  • Création de Jeux
  • Linux
  • Programmation
  • Steam Deck
  • Hardware
La vidéo du moment