Domanda

  

Eventuali duplicati:
   è Java “pass-by-reference”?

Ho trovato un metodo Java insolito oggi:

private void addShortenedName(ArrayList<String> voiceSetList, String vsName)
{
     if (null == vsName)
       vsName = "";
     else
       vsName = vsName.trim();
     String shortenedVoiceSetName = vsName.substring(0, Math.min(8, vsName.length()));
     //SCR10638 - Prevent export of empty rows.
     if (shortenedVoiceSetName.length() > 0)
     {
       if (!voiceSetList.contains("#" + shortenedVoiceSetName))
         voiceSetList.add("#" + shortenedVoiceSetName);
     }
}

Secondo tutto quello che ho letto su comportamento di Java per il passaggio di variabili, oggetti complessi o no, questo codice dovrebbe fare esattamente nulla. Quindi, um ... mi manca qualcosa qui? C'è qualche sottigliezza che è stato perso su di me, o se questo codice appartiene a thedailywtf?

È stato utile?

Soluzione

Come ha detto Rytmis, Java passa i riferimenti di valore. Ciò significa che si può legittimamente chiamare mutando metodi sui parametri di un metodo, ma non è possibile riassegnare e si aspettano il valore di propagare.

Esempio:

private void goodChangeDog(Dog dog) {
    dog.setColor(Color.BLACK); // works as expected!
}
private void badChangeDog(Dog dog) {
    dog = new StBernard(); // compiles, but has no effect outside the method
}

Modifica Che cosa questo significa in questo caso è che, anche se voiceSetList potrebbe il cambiamento come un risultato di questo metodo (che potrebbe avere un nuovo elemento aggiunto ad esso), il modifiche vsName non saranno visibili all'esterno del metodo. Per evitare confusione, spesso contrassegna i miei parametri del metodo final, che impedisce loro di essere riassegnato (accidentalmente o meno) all'interno del metodo. Questo avrebbe mantenuto il secondo esempio da compilare a tutti.

Altri suggerimenti

Java passa i riferimenti di valore , in modo da ottenere una copia del riferimento, ma l'oggetto di riferimento è lo stesso. Quindi questo metodo non modificare l'elenco di ingresso.

I riferimenti stessi sono passati per valore.

Da Java Come programmare, 4th Edition by Deitel & Deitel: (. Pg 329)

  

A differenza di altri linguaggi, Java non permette al programmatore di scegliere se passare   ogni argomento per valore o per riferimento. variabili di tipo di dati primitivi vengono sempre passati   in valore. Gli oggetti non vengono passati a metodi; piuttosto, i riferimenti agli oggetti vengono passati   metodi. I riferimenti stessi sono passati per valore, una copia di un punto di riferimento è passato   a un metodo. Quando un metodo riceve un riferimento a un oggetto, il metodo può manipolare   l'oggetto direttamente.

Utilizzato questo libro quando apprendimento di Java in un college. Brillante di riferimento.

Ecco un buon articolo che spiega esso. http://www.javaworld.com/javaworld /javaqa/2000-05/03-qa-0526-pass.html

Bene, può manipolare il ArrayList - che è un oggetto ... se si passa un riferimento a un oggetto in giro (anche passato per valore), le modifiche a tale oggetto si rifletterà al chiamante. E 'questa la domanda?

Credo che si sono confusi perché VSNAME viene modificato. Ma in questo contesto, è solo una variabile locale, allo stesso esatto livello shortenedVoiceSetName.

Non è chiaro per me quello che la domanda esatta all'interno del codice è. Java è passare per valore, ma le matrici sono pass-by-di riferimento mentre passano nessun oggetto, ma solo i puntatori! Gli array sono costituiti da puntatori, non oggetti reali. Questo li rende molto veloce, ma li rende anche pericoloso da maneggiare. Per risolvere questo problema, è necessario clonare loro di ottenere una copia, e anche allora si clonare solo la prima dimensione della matrice.

Per maggiori dettagli si veda la mia risposta qui: In Java, qual è una copia? (veda anche il mio altre risposte)

A proposito, ci sono alcuni vantaggi come array sono solo i puntatori: si può (ab) usarli come oggetti sincronizzati

!
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top