Dans une boucle Java améliorée for, est-il prudent de supposer que l'expression à boucler ne sera évaluée qu'une seule fois?
Question
En Java, une boucle for-each.
Si j’ai une méthode qui génère un tableau, appelée genArray ()
.
Dans le code suivant, le tableau sera-t-il à chaque fois re-généré en appelant genArray ()
?
Ou bien Java appellera-t-il une fois la méthode et stockera-t-il une copie du tableau?
for (String s : genArray())
{
//...
}
Merci
La solution
À propos de l'instruction améliorée pour , les spécifications du langage Java écrivent:
La déclaration améliorée pour a forme:
EnhancedForStatement: for ( VariableModifiersopt Type Identifier: Expression) Statement
L'expression doit avoir le type
Iterable
ou bien il doit s'agir d'un type de tableau (§10.1), ou un temps de compilation une erreur se produit.La portée d'une variable locale déclarée dans la partie FormalParameter d'un
amélioré pour
, instruction (§14.14) est la déclaration contenueLa signification du
amélioré pour
déclaration est donnée par traduction en unede base pour
.Si le type de
Expression
est un sous-type deIterable
, puis laissezI
le type de l'expression Expression.iterator ()
. L'instructionaméliorée pour
est équivalente à une instructionde base pour
du forme:for (I #i = Expression.iterator(); #i.hasNext(); ) { VariableModifiersopt Type Identifier = #i.next(); Statement }
Où
#i
est un compilateur généré identifiant distinct de tout autres identifiants (générés par le compilateur ou autrement) qui sont dans la portée (§6.3) au point où le amélioré pour déclaration se produit.Sinon, l'expression est nécessairement a un type de tableau,
T []
. SoitL1 ... Lm
être la séquence (éventuellement vide) de étiquettes immédiatement avant laamélioré pour
. Puis le signification de la déclaration améliorée est donné par lede base suivant pour
déclaration:T[] a = Expression; L1: L2: ... Lm: for (int i = 0; i < a.length; i++) { VariableModifiersopt Type Identifier = a[i]; Statement }
Où a et i sont générés par le compilateur identifiants qui sont distincts de tout autres identifiants (générés par le compilateur ou autrement) qui sont dans la portée au point où le amélioré pour la déclaration se produit.
Ainsi, dans votre cas, genArray ()
ne renvoie pas un sous-type Iterable
, mais un type de tableau. Votre instruction pour
améliorée est équivalent à l'instruction de base suivante pour
:
String[] a = genArray();
...
for (int i = 0; i < a.length; i++) {
String s = a[i];
// ...
}
Et genArray ()
ne sera donc appelé qu'une fois (mais la réponse actuellement acceptée est partiellement fausse).
Autres conseils
Java appellera une fois genArray (), obtiendra l’objet itérateur et l’appellera plusieurs fois.
Il ne faut s’habituer qu’une fois. C’est la même chose que d’appeler ceci:
String[] strings = genArray();
for (String s : strings) {
...