2011-03-29 9 views
7

encontrado esta pregunta herepasa a la pregunta/bloque finally

Y no puede entender por qué el primer caso se imprime CoolReturn+1 y en el segundo caso CoolReturn? ¿Como funciona?

Gracias

====================

lo que se imprimirá?

public void testFinally(){ 
    System.out.println(setOne().toString()); 

} 

protected StringBuilder setOne(){ 
    StringBuilder builder=new StringBuilder(); 
    try{ 
     builder.append("Cool"); 
     return builder.append("Return"); 
    }finally{ 
     builder.append("+1"); 
    } 
} 

Respuesta: CoolReturn + 1

un poco más difícil:

public void testFinally(){ 
    System.out.println(setOne().toString()); 

} 

protected StringBuilder setOne(){ 
    StringBuilder builder=new StringBuilder(); 
    try{ 
     builder.append("Cool"); 
     return builder.append("Return"); 
    }finally{ 
     builder=null; /* ;) */ 
    } 
} 

Respuesta: CoolReturn

+0

Mira el contenido de cada bloque 'finally'. – mre

+2

@noob Creo que su objetivo es determinar por qué el comportamiento es lo que es. – corsiKa

+0

http://stackoverflow.com/questions/4625650/object-reference-set-to-null-in-finally-block/4625656#4625656 – reggie

Respuesta

7

Considérese

protected StringBuilder setOne(){ 
    StringBuilder builder=new StringBuilder(); 
    try{ 
     builder.append("Cool"); 
     return builder.append("Return"); 
    }finally{ 
     builder.append("+1"); 
    } 
} 

como

protected StringBuilder setOne(){ 
    StringBuilder builder=new StringBuilder(); 
    try{ 
     builder.append("Cool"); 
     StringBuilder ret = builder.append("Return"); // 1 
     return ret; // 2 
    }finally{ 
     builder.append("+1"); //3 
    } 
} 

línea 1 se ejecuta, el builder se devuelve como resultado. A continuación, se ejecuta la línea 3 y se agrega el builder con +1, luego se devuelve el ret que es una "referencia" al objeto al que hace referencia el builder. Lo mismo es para el segundo caso. Espero que esté claro.

+0

No es una referencia a la referencia del objeto por el constructor. Es una copia de la referencia. Si fuera una referencia, entonces también se establecerá en nulo. – TofuBeer

0

El fin operador siempre funciona tan constructor se volvió y luego el 1 es devuelto.

En el segundo, el constructor se establece en nulo, por lo que no hay nada más que agregar. Podría ser igual de fácil construir = "" en el último.

2

Cuando devuelve builder.append ("Volver"), se inserta en la pila una copia de la referencia a la variable del constructor. Entonces el constructor se establece en nulo. La persona que llama luego saca la copia de la referencia de la pila.

6

La primera de ellas:

El fin será siempre el fuego (suponiendo que el machien no bloquee o nada). Entonces, después de la devolución, el bloque finalmente dispara y, como tiene una referencia al objeto "generador", le agrega el token adicional.

La segunda:

El bloque finally incendios al igual que antes, pero establece la referencia al constructor para ser nulo. El objeto todavía existe, porque todavía tiene un enlace a él.

1

En el primer ejemplo, en el bloque finally, manipula el generador de cadenas con append.

En el segundo ejemplo, en el bloque finally, cambia el puntero al generador de cadenas para que sea el puntero nulo, después de devolver el resultado del método de agregar. Esto no modifica el generador de cadenas al que anteriormente apuntabas de ninguna manera.

EDITAR: Parece que me golpeó.

0

Esto funciona porque la expresión return se evalúa antes de que se ejecute el bloque finally. Esto es bastante evidente cuando invoca un método en la instrucción return de su código y agrega instrucciones de registro a sus bloques try y finally. La explicación relevante se puede encontrar en el JLS 3rd edition, 14.20.2. Esta es una de las razones por las cuales las declaraciones return en el bloque finally producen una advertencia en IDE como Eclipse.

maravilloso Un código de ejemplo:

def doSomething() { 
    def f = "something"; 
    try { 
     return f += doSomethingMore() 
    } finally { 
     println "before nulling";   
     f = null; 
     println "after nulling"; 
    } 
} 

def doSomethingMore() { 
    println "doSomethingMore called" 
    return "-wow"; 
} 

println "output from call ---> " + doSomething() 
Cuestiones relacionadas