Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Une question de style

13 réponses
Avatar
c.triffault
bonsoir,

je me pose la question suivante :
soit une m=E9thode quelconque.
vaut-il mieux faire :

process(String var){

Connection conn =3D null;
du code......
conn =3D new Connection();

//ou :
Connection conn =3D new Connection();
.
.
.
.

A la fin, conn =3D null.
}

Bref: vaut-il mieux d=E9clarer au d=E9but de la m=E9thode toutes les
ressources dont on aura besoin, puis instancier au fur et =E0 mesure ou
tout faire en une passe ?

Deuxi=E8me question : j'ai pris l'habitude de mettre les objets donc je
ne me sers plus =E0 null : utile ou pas ?

Voil=E0, c'est pas existentiel, mais comme j'arrive pas =E0 trancher, je
viens vous demander un avis =E9clair=E9 .

Merci pour vos lumi=E8res !

10 réponses

1 2
Avatar
Rémi Cocula
wrote:

bonsoir,

je me pose la question suivante :
soit une méthode quelconque.
vaut-il mieux faire :

process(String var){

Connection conn = null;
du code......
conn = new Connection();

//ou :
Connection conn = new Connection();
.
.
.
.

A la fin, conn = null.
}

Bref: vaut-il mieux déclarer au début de la méthode toutes les
ressources dont on aura besoin, puis instancier au fur et à mesure ou
tout faire en une passe ?


A mon avis ca ne change rien du point de vue du compilateur.
Après comme tu dis c'est une question de style.
Personnellement, je trouve que la déclaration de toute les variables en
début de méthode est une lourdeur.
Note que parfois tu es contraint de déclarer les variables à l'avance à
cause de l'utilisation des blocks try/catch.


Deuxième question : j'ai pris l'habitude de mettre les objets donc je
ne me sers plus à null : utile ou pas ?

Utile dans quel sens ?

Ca ne veut rien dire.
"mettre à null un objet" comme tu dis c'est supprimer une référence sur une
instance de classe.
Ca ne veut pas dire que ton objet est mis à vide ou supprimé. Si par
ailleurs il existe d'autres références sur cet objets , il reste bien
présent en mémoire.
Bref, la meilleur chose est encore de bien maitriser les références sur les
objets.

Exemple :

public static void main(String[] args){

String s = "toto";
Vector v = new Vector();
v.add(s);
s=null; // il reste une référence à la chaine "toto" dans le vector v

}

Avatar
David Molinier
{...]

Bref: vaut-il mieux déclarer au début de la méthode toutes les
ressources dont on aura besoin, puis instancier au fur et à mesure ou
tout faire en une passe ?


Personnellement, je trouve que ça augmente la clarté du code de déclarer
et de définir les objets au plus près de là où on les utilise.

Donc ni solution 1 ni solution 2, mais solution 3 :

process(String var){

du code......
.
.
.
Connection conn = new Connection();
.
.
.
.
}

Deuxième question : j'ai pris l'habitude de mettre les objets donc je
ne me sers plus à null : utile ou pas ?


Je dirais non. Sorti du scope de ta méthode, ton objet n'est plus
référencé, donc sera garbage collecté, AMA.

Et je rajouterai que, dans le même souci que précédemment, ça nuit à la
clarté du code.

--
David Molinier <*>

Avatar
c.triffault
Bref: vaut-il mieux déclarer au début de la méthode toutes les
ressources dont on aura besoin, puis instancier au fur et à mesure
ou


tout faire en une passe ?


Personnellement, je trouve que ça augmente la clarté du code de
déclarer

et de définir les objets au plus près de là où on les utilise.

Donc ni solution 1 ni solution 2, mais solution 3 :
ok, c'est parce que en fait, on fait normalement (en C par ex) la

distinction entre déclaration et initialisation et je me demandais si
c'était pertinent.
Deuxième question : j'ai pris l'habitude de mettre les objets donc
je


ne me sers plus à null : utile ou pas ?


Je dirais non. Sorti du scope de ta méthode, ton objet n'est plus
référencé, donc sera garbage collecté, AMA.
Oui, je sais bien qu'il sera GCollecté mais je me suis dit que 1 cela

permettait de bien montrer au développeur que l'objet ne serait plus
utilisé par la suite et que 2, ca évite au GC de "se poser des
questions".

Et je rajouterai que, dans le même souci que précédemment, ça
nuit à la

clarté du code.
Question d'opinion donc :)


En ce qui concerne le String contenu dans le Vector, je suis d'accord,
of course.


Dans tous les cas, merci pour vos réponses.


Avatar
Sébastien
Rémi Cocula wrote:
wrote:


bonsoir,

je me pose la question suivante :
soit une méthode quelconque.
vaut-il mieux faire :

process(String var){

Connection conn = null;
du code......
conn = new Connection();

//ou :
Connection conn = new Connection();
.
.
.
.

A la fin, conn = null.
}

Bref: vaut-il mieux déclarer au début de la méthode toutes les
ressources dont on aura besoin, puis instancier au fur et à mesure ou
tout faire en une passe ?



A mon avis ca ne change rien du point de vue du compilateur.
Après comme tu dis c'est une question de style.
Personnellement, je trouve que la déclaration de toute les variables en
début de méthode est une lourdeur.
Note que parfois tu es contraint de déclarer les variables à l'avance à
cause de l'utilisation des blocks try/catch.



Tout à fait d'accord. On n'est plus à l'époque du C où il fallait déclarer toutes les variables
locales en début de fonction alors profitons en!
De plus, le fait de déclarer les variables au moment où l'on s'en sert est, à mon avis, un avantage
pour sa clareté.

Sébastien


Avatar
Black Myst
wrote:
bonsoir,

Deuxième question : j'ai pris l'habitude de mettre les objets donc je
ne me sers plus à null : utile ou pas ?
Pour une variable locale, c'est equivalent... la variable sera détruite

et donc la référence perdu.

En revanche, la mise à null d'une variable de classe, ou d'une variable
locale avant la fin du block peut etre utile, surtout si l'objet
représente une occupation mémoire significative (tableau, image, ...)

Avatar
Wismerhill
ecrivit le 24/02/2005 22:24 :
bonsoir,

je me pose la question suivante :
soit une méthode quelconque.
vaut-il mieux faire :

process(String var){

Connection conn = null;
du code......
conn = new Connection();

//ou :
Connection conn = new Connection();
.
.
.
.

A la fin, conn = null.
}

Bref: vaut-il mieux déclarer au début de la méthode toutes les
ressources dont on aura besoin, puis instancier au fur et à mesure ou
tout faire en une passe ?


Relicat du C. Il est plus clair de définir les variables au moment
précis où on en a besoin. Le compilateur optimisera les boucles. Ex:

for(int i = 0; i < foo; ++i)
{
Object obj = array[i];
...
}

Dans ce cas, inutile de sortir de la boucle la variable obj, le
compilo le fera.

Avatar
c.triffault
"le compilo le fera" . Ca me gêne ce genre d'expressions :)
Bien que les compilos deviennent intelligents et permettent d'optimiser
ce genre de code, je pense qu'il tjs bon de se discipliner et de se
poser des questions d'optimisation, sans non plus sombrer dans
l'excès maniaque ;) ni à l'inverse se dire : le compilo le fera :)

bon we cpdt sur ces considérations stylistiques :)
Avatar
Wismerhill
ecrivit le 25/02/2005 12:17 :
"le compilo le fera" . Ca me gêne ce genre d'expressions :)


Il ne faut pas. Le compilo est un outil pour faciliter ton travail, ça
veut dire aussi pour t'aider à pondre du code clair et maintenable.

Bien que les compilos deviennent intelligents et permettent d'optimiser
ce genre de code, je pense qu'il tjs bon de se discipliner et de se
poser des questions d'optimisation, sans non plus sombrer dans
l'excès maniaque ;) ni à l'inverse se dire : le compilo le fera :)


L'optimisation est la source de tous les maux.(c)

Dans ce cas-ci, la discipline consiste à fournir du code lisible et
propre, non pas à coder n'importe comment par paresse.

bon we cpdt sur ces considérations stylistiques :)


Propreté, propreté.

Avatar
Derek Sagan
wrote:
bonsoir,

je me pose la question suivante :
soit une méthode quelconque.
vaut-il mieux faire :

process(String var){

Connection conn = null;
du code......
conn = new Connection();

//ou :
Connection conn = new Connection();
.
.
.
.

A la fin, conn = null.
}

Bref: vaut-il mieux déclarer au début de la méthode toutes les
ressources dont on aura besoin, puis instancier au fur et à mesure ou
tout faire en une passe ?


Si l'objet contient des ressources externes (fichier ouvert, connection
réseau, statement jdbc...), ce n'est pas une question de style mais de
robustesse. Non seulement il faut le faire en deux fois mais il ne faut
pas oublier d'appeler les éventuelles méthodes libérant des ressources
externes ou système sur l'objet qu'on n'utilise plus, et ce dans une
clause finally.
Comme l'évoquait Rémi, le bloc try/(catch/)finally impose la déclaration
à l'avance.

Connection conn = null;
try {
conn = myConnectinPool.getConnection();
//...
} finally {
try { conn.close(); } catch (Exception e) {}
}

Parmi les objets ayant des ressources externes (= non libérables par le
GC), il y a en particulier: Connection Statement ResultSet InputStream
OutputStream Socket.

Sébastien parlait des avantage de Java sur le vieux langage C, la
comparaison n'est pas sans intérêt.
Il ne faut pas perdre de vue qu'en C il fallait libérer les ressources
avec close, fclose, shmdt, pthread_exit et free (j'en passe et des
meilleurs). Alors qu'en Java (et dans tout langage pourvu d'un garbage
collector) tout est "beaucoup" plus simple: il faut libérer les
ressources avec tous les mêmes appels sauf un, free. Le GC ne ferme pas
les fichiers, les connections réseau, ni les fenêtres ou le gaz dans la
cuisine...
Comme en plus il y a des exceptions (comme en C++ mais pas comme en C),
il faut penser à effectuer ces tâches dans un bloc finally, sinon en cas
d'erreur il y a une fuite de ressource.

Deuxième question : j'ai pris l'habitude de mettre les objets donc je
ne me sers plus à null : utile ou pas ?


Après si tu veux mettre conn à null, ça ne change pas grand chose pour
le GC, mais peut-être pour d'autres bouts de ton code si tu te ressert
de la même variable.

Voilà, c'est pas existentiel, mais comme j'arrive pas à trancher, je
viens vous demander un avis éclairé .

Merci pour vos lumières !


a+

Avatar
Jean-Philippe Caruana
Si l'objet contient des ressources externes (fichier ouvert, connection
réseau, statement jdbc...), ce n'est pas une question de style mais de
robustesse. Non seulement il faut le faire en deux fois mais il ne faut
pas oublier d'appeler les éventuelles méthodes libérant des ressources
externes ou système sur l'objet qu'on n'utilise plus, et ce dans une
clause finally.


exactement
dans le cas des BDD, tu peux bloquer les autres accès si leur nombre est
limité : il faut donc obligatoirement libérer les ressources.

Comme l'évoquait Rémi, le bloc try/(catch/)finally impose la déclaration
à l'avance.

Connection conn = null;
try {
conn = myConnectinPool.getConnection();
//...
} finally {
try { conn.close(); } catch (Exception e) {}
}


moi je testerais la nullité avant la destruction et je garderai le catch
pour autre chose que le finally (cépabo d'empiler les try-catch je
trouve, qd on peut l'éviter)

Connection conn = null;
try {
conn = myConnectinPool.getConnection();
//...
} catch (Exception e){
//...
} finally {
if (conn != null) conn.close();
}

mes 0.2 euro

--
jpc
http://www.enstimac.fr/~caruana/

1 2