2010-08-30 6 views
11

En regardant à travers le code source de l'API Java, je vois souvent les paramètres de la méthode réaffectés aux variables locales. Pourquoi cela a-t-il déjà été fait?Pourquoi les paramètres de méthode sont-ils réaffectés aux variables locales?

void foo(Object bar) { 
    Object baz = bar; 
    //... 
} 

C'est dans java.util.HashMap

public Collection<V> values() { 
    Collection<V> vs = values; 
    return (vs != null ? vs : (values = new Values())); 
} 
+6

Donne-nous quelques exemples de méthodes à regarder? – jjnguy

+1

Je pense que Doug Lea est connu pour faire cela dans le paquet 'concurrent'? Peut-être que je me suis trompé, cependant (auquel cas je m'excuse). Relatif/dupe: http://stackoverflow.com/questions/3080074/why-would-anyone-make-additional-local-variable-just-to-put-final-keyword-on-it et http: // stackoverflow. com/questions/2785964/in-arrayblockingqueue-pourquoi-copier-final-membre-champ-dans-local-final-variable; OK Je me suis trompé, mais Doug Lea fait quelque chose de similaire avec les variables locales 'final'. – polygenelubricants

+0

Copie possible de [Pourquoi n'utilise-t-il pas directement le champ d'instance, mais l'affecte à une variable locale?] (Https://stackoverflow.com/questions/7943763/why-it-doesnt-use-the-instance- field-directement-but-assigne-it-to-a-local-variab) – anacron

Répondre

4

Ceci est la règle de sécurité des threads/meilleure performance. values dans HashMap est volatile. Si vous assignez une variable à une variable locale, elle devient une variable de pile locale qui est automatiquement sécurisée. De plus, la modification de la variable de pile locale ne force pas 'happen-before' donc il n'y a pas de pénalité de synchronisation lors de l'utilisation (par opposition à volatil quand chaque lecture/écriture vous coûtera d'acquérir/libérer un verrou)

+0

Mais un paramètre de méthode est également une variable de pile locale. – EJP

+0

@EJP, @polygenelubricants. Bonne prise. Dans ce cas, je suis entièrement d'accord que cette partie de la question est couverte dans http://stackoverflow.com/questions/2785964/in-arrayblockingqueue-why-copy-final-member-field-into-local-final-variable (en supposant que avoir une copie finale n'est pas exclusivement pour une utilisation en classe interne) –

0

Je dois regarder quelques exemples réels, mais la seule raison pour laquelle je peux penser à faire est de savoir si la valeur d'origine doit être conservé pour un calcul à la fin de la méthode. Dans ce cas, déclarer l'une des "variables" final le rendrait clair.

+0

Non, certaines personnes le font religieusement. Je ne sais pas pourquoi. –

+0

J'ai finalement trouvé ce que j'ai vu auparavant. Ceci est dans java.util.HashMap public Collection values ​​() { Collection vs = valeurs; return (vs! = Null? Vs: (values ​​= new Values ​​())); } – initialZero

+0

@initialZero - c'est une variable membre, plutôt qu'un paramètre de méthode, qui est copiée dans une variable locale. C'est un peu plus commun, en particulier dans les classes conçues pour un accès simultané par plusieurs threads. Cependant, 'HashMap' n'est pas une telle classe, donc la seule raison que je peux voir est pour" performance "; la lecture d'un local est plus rapide que la lecture d'une variable membre. Cependant, ce n'est pas une différence assez importante pour justifier l'obscurcissement du code comme celui-ci, et ils n'enregistrent qu'une seule lecture, et ajoutent une variable locale en écriture, donc je ne suis pas sûr que cela aurait un réel avantage. – erickson

Questions connexes