2009-07-10 5 views
3

Juste une petite question sur la façon dont les paramètres sont passés en Java ...Les paramètres de la fonction Java sont-ils toujours transmis valeur par valeur?

 
... 
      if ((index = stdout.indexOf(pattern)) != -1) { 
       tidy(stdout, index + pattern.length()); 
       return true; 
      } else if ((index = stderr.indexOf(pattern)) != -1) { 
       tidy(stderr, index + pattern.length()); 
       return true; 
... 

    private void tidy(StringBuffer buffer, int i) { 
     logger.info("Truncating buffer: " + buffer); 
     buffer = new StringBuffer(buffer.substring(i)); 
     logger.info("Buffer now: " + buffer); 
    } 

Dans ce cas, sera stdout et stderr (utilisés comme paramètres dans bien rangé()) ont leurs valeurs changé à nouveau StringBuffer (tampon. sous-chaîne (i))? Mon hypothèse est qu'ils seront comme des variables d'objet (pointeurs d'objet) sont toujours passés par valeur?

+0

voir ceci pour une explication en profondeur avec des exemples http://javadude.com/articles/passbyvalue.htm – akf

+6

voir aussi ce post: http://stackoverflow.com/questions/40480/is-java-pass- par référence – akf

Répondre

14

Vous déformez ce qui se passe ici - les références d'objet sont passées par valeur (une copie de la référence est faite), donc stdout et stderr ne sont pas modifiés lorsque vous appelez tidy. Les copies qui en sont faites sont modifiées lorsque vous exécutez la ligne 2 de tidy. Le paramètre passant en Java est une source de confusion pour beaucoup de gens. Voici a good explanation.

+0

merci! J'aime votre référence à ce problème de «valeur de passage» –

+0

Je n'appellerais pas cela une bonne explication ... Je ne comprends pas. – Victor

1

Non, stdout et stderr ne seront pas modifiés, et oui, les paramètres sont transmis par valeur.

La variable "buffer" sera mise à égalité avec stdout, ce qui signifie que le tampon pointera sur le même objet au début. Lorsque le tampon est modifié pour pointer vers un nouvel objet, l'ancienne référence stdout pointe toujours vers l'ancien objet.

0

Votre hypothèse est incorrecte. Pourquoi?

Parce que les paramètres de fonction sont toujours passés en valeur.

Quand vous faites:

buffer = new StringBuffer(buffer.substring(i)); 

vous assignez une nouvelle StringBuffer à une référence locale qui a été copié à partir de la référence des paramètres. Par conséquent, le tampon original ne change pas.

2

Les paramètres Java sont toujours valeur par passe, période.

est ici un article mignon expliquant le phénomène: http://www.javaranch.com/campfire/StoryPassBy.jsp

Dans votre cas, il n'a pas d'importance si elle est ou PBR pv, parce que vous réattribuant sb à un nouvel objet (en appelant buffer = new StringBuffer(...) et buffer.subString(...) ne mute pas l'objet lui-même).

3

De James Gosling dans "Le langage de programmation Java":

"... Il y a exactement un paramètre en mode de passage en Java - passer la valeur - et qui garde les choses simples ..."

Je pense que c'est l'autorité finale à ce sujet.

+0

+1 pour passer l'ironie par la valeur –

Questions connexes