2015-01-02 18 views
13

Attualmente sto lavorando sull'ottimizzazione del codice dove sto usando try.. finally per deferenza dei miei oggetti.Come provare ... finalmente funziona internamente

Ma ho la confusione che il modo in cui viene restituito un oggetto viene gestito quando sto creando un riferimento null a un oggetto nel mio blocco finally. ??

Durante la restituzione di un oggetto in un blocco try, verrà creata un'istruzione precompilata durante la compilazione? o creare un nuovo riferimento in heap mentre si tratta dell'istruzione return? o semplicemente restituire un riferimento corrente di un oggetto?

Di seguito è riportato il mio codice di ricerca.

public class testingFinally{ 
    public static String getMessage(){ 
     String str = ""; 
     try{ 
      str = "Hello world"; 
      System.out.println("Inside Try Block"); 
      System.out.println("Hash code of str : "+str.hashCode()); 
      return str; 
     } 
     finally { 
      System.out.println("in finally block before"); 
      str = null; 
      System.out.println("in finally block after"); 
     } 
    } 

    public static void main(String a[]){ 
     String message = getMessage(); 
     System.out.println("Message : "+message); 
     System.out.println("Hash code of message : "+message.hashCode()); 
    } 
} 

uscita è:

All'interno Prova Blocca
codice hash di str: -832.992.604
nel infine bolck prima
nel blocco finally dopo
Messaggio: Ciao mondo
codice Hash del messaggio: -832992604

Sono molto sorpreso quando vedo che sia l'oggetto che restituisce che l'oggetto chiamante hanno lo stesso codice hash. Quindi sono confuso riguardo al riferimento all'oggetto.

Per favore aiutami a chiarire questo fondamentale.

+2

hashcode viene creato in base al contenuto e non all'indirizzo di riferimento o qualcosa del genere. Quindi qual è la confusione? – SMA

+0

Grazie per la pronta risposta. la mia confusione è che sto rendendo il mio oggetto nullo nel mio blocco finale. quindi dove si trova l'oggetto di ritorno e come ?? – Pratik

+1

[JLS-14.20.2. L'esecuzione di 'try-finally' e' try-catch-finally'] (https://docs.oracle.com/javase/specs/jls/se7/html/jls-14.html#jls-14.20.2) potrebbe aiuta a chiarire la tua confusione su "finalmente". È importante notare che Java 'String' è immutabile. Quindi hai già restituito una copia di quel valore, in definitiva non puoi modificare l'istanza restituita. Se hai restituito un 'StringBuilder' e hai chiamato' setLength (0) 'alla fine, avresti ottenuto una lunghezza' StringBuilder' nel tuo chiamante. –

risposta

12

Il metodo non è esattamente restituire un oggetto. Restituisce un riferimento a un oggetto. L'oggetto a cui fa riferimento il riferimento rimane lo stesso dentro e fuori la chiamata al metodo. Poiché si tratta dello stesso oggetto, l'hashcode sarà lo stesso.

Il valore di str al momento di return str è un riferimento alla stringa "Hello World". La dichiarazione restituisce il valore di str e lo salva come valore di ritorno del metodo.

Quindi viene eseguito il blocco finally, che ha la possibilità di modificare il valore di ritorno contando la propria dichiarazione di ritorno .La modifica del valore di str all'interno del blocco finally non modifica il valore di ritorno già impostato, verrà eseguita solo un'altra istruzione di ritorno.

Poiché l'impostazione da str a null non ha alcun effetto, è possibile rimuovere istruzioni come questa. Andrà fuori campo non appena il metodo ritorna comunque, quindi non aiuta con la garbage collection.

+0

È davvero un aiuto completo per me. Molte grazie. Ho il dubbio che fare oggetto come null non servirà a garbage collection ??. Non c'è più riferimento nello spazio heap per questo tipo di oggetti che sono nel metodo ?? – Pratik

+2

@prattpratt Quando il metodo restituisce, le variabili all'interno non esistono più, quindi i valori non hanno più importanza. Non contano come riferimenti agli oggetti, quindi gli oggetti a cui si riferiscono possono essere raccolti, purché non esistano altri riferimenti. – fgb

+0

@prattpratt - Ci sarà uno slot per l'indirizzo di ritorno (in cima allo stack) sul quale deve essere inserito il riferimento da restituire. Quindi, quando si incontra il ritorno della prova, il riferimento di "Hello World" viene inviato lì. Quindi, qualunque cosa accada dopo (riassegnare il riferimento a 'null'), non cambierà il valore * restituito *. Se chiami 'return str' in * finally *, il valore di' str' verrà estratto dallo stack e null verrà aggiornato al suo posto. Quindi verrà restituito "null". – TheLostMind

0

Hashcode() non serve per mostrare un riferimento. Invece, viene usato hashcode per verificare se 2 stringhe sono uguali tra loro. Si prega di fare riferimento a http://docs.oracle.com/javase/6/docs/api/java/lang/String.html#hashCode()

Restituisce un codice di hash per questa stringa. Il codice hash per un oggetto String viene calcolato come s [0] * 31^(n-1) + s [1] * 31^(n-2) + ... + s [n-1]

Poiché entrambe le stringhe hanno lo stesso valore, ovviamente il codice hash è lo stesso.

+0

Anche in questo caso, il richiedente attendeva che 'str' fosse nullo, quindi avrebbe dovuto generare un' NullPointerException'. –

+0

No - Java passa il valore e non il riferimento. Il valore restituito e il valore modificato in infine stanno avendo riferimenti diversi. – Rudy

+0

Sì, questa è la risposta. Questo è ciò che OP non ha capito. Non come vengono calcolati i codici hash. –

1

Base sul JLS 14.20.2 Execution of try-catch-finally

If execution of the try block completes normally, then the finally block is executed, and then there is a choice:  
    If the finally block completes normally, then the try statement completes normally. 
    If the finally block completes abruptly for reason S, then the try statement completes abruptly for reason S. 

Spero che questo aiuto :)

+0

@Downvoter ci sono problemi con la mia risposta? :) – hqt

+1

Non il downVoter, ma questo non risponde alla domanda OPs. – TheLostMind

+1

@TheLostMind Base sul codice che ha provato e il suo commento sotto il suo post. 'Grazie per la tua pronta risposta. la mia confusione è che sto rendendo il mio oggetto nullo nel mio blocco finale. quindi, dove si trova l'oggetto di ritorno e come ?? "Non penso di averlo frainteso :) – hqt

Problemi correlati