2009-03-17 8 views
14

Dado el siguiente código, ixAdd hará lo que cabría esperar, i. mi. devuelve el valor de ix antes del incremento, pero incrementa el miembro de la clase antes de abandonar la función?En Java, ¿cómo actúa un operador de incremento de inserción en una declaración de devolución?

class myCounter { 
    private int _ix = 1; 

    public int ixAdd() 
    { 
     return _ix++; 
    } 
} 

no estaba muy seguro de si las normas habituales para después de la subasta/pre también se aplicarían en los estados de retorno, cuando el programa sale del marco de pila (o lo que sea en Java) de la función.

+1

¿Por qué no lo intentas? –

+2

ehm .. quieres decir, pegar el código de arriba en mi editor y ejecutarlo? No lo sé, lo siento. :-p Iré a tomar una taza de café ... –

+0

votado de cerca ... Pensé que el autor podría cerrarlo de inmediato? –

Respuesta

25

La parte clave es que un incremento/decremento posterior ocurre inmediatamente después de evaluar la expresión. No solo ocurre antes de que se produzca el retorno, sino que ocurre antes de que se evalúen las expresiones posteriores. Por ejemplo, supongamos que usted escribió:

class myCounter { 
    private int _ix = 1; 

    public int ixAdd() 
    { 
     return _ix++ + giveMeZero(); 
    } 

    public int giveMeZero() 
    { 
     System.out.println(_ix); 
     return 0; 
    } 
} 

Eso sería imprimir el resultado incrementado también, porque el incremento ocurre antes giveMeZero() se llama.

+0

Gracias por la respuesta, Jon. Como Paul Tomblin señaló, escribir el código en mi editor en lugar de la publicación también lo habría respondido. Pero ahora obtuve más de lo que pedí. –

+0

@Jon: para las personas que vienen de C a Java (que será un montón de gente), esto es algo bueno de señalar. Como usuario de Java desde hace mucho tiempo que utilizó por primera vez C durante mucho, mucho tiempo, no sabía que Java definía cómo funciona ++ con mucha más claridad que C. ¡Aprendí a evitar el uso "inteligente" ++ de C! – Eddie

+0

_No solo ocurre antes de que se produzca el retorno_, sino que la declaración de devolución no devuelve el valor incrementado si es una variable local. Tu ejemplo muestra una variable global. – ernesto

1

Sí, las reglas habituales se aplican para el incremento posterior incluso en una declaración de devolución. Básicamente, lo que hará en un nivel bajo es almacenar el valor de retorno en un registro, luego incrementar el miembro de la clase y luego regresar del método.

Puede ver esto en a later answer a esta pregunta que muestra el código de bytes.

0

Sí, lo hace.

Pero no hagas eso, es malo tener efectos secundarios en las expresiones.

+0

El efecto secundario aquí es muy intencionado y no puedo ver que cause ningún daño. –

+0

Pero hace que sea difícil de entender, como lo muestra tu pregunta. – starblue

16

Bueno, veamos el código de bytes (utilizar javap -c <classname> que verlo usted mismo):

Compiled from "PostIncTest.java" 
class myCounter extends java.lang.Object{ 
myCounter(); 
    Code: 
    0: aload_0 
    1: invokespecial #1; //Method java/lang/Object."<init>":()V 
    4: aload_0 
    5: iconst_1 
    6: putfield #2; //Field _ix:I 
    9: return 

public int ixAdd(); 
    Code: 
    0: aload_0 
    1: dup 
    2: getfield #2; //Field _ix:I 
    5: dup_x1 
    6: iconst_1 
    7: iadd 
    8: putfield #2; //Field _ix:I 
    11: ireturn 

} 

Como se puede ver, las instrucciones 6 y 7 en ixAdd() manejar el incremento antes del retorno. Por lo tanto, como cabría esperar, el operador de decremento sí tiene un efecto cuando se usa en una declaración de devolución. Observe, sin embargo, que hay una instrucción dup antes de que aparezcan estos dos; el valor incrementado (por supuesto) no se refleja en el valor de retorno.

0

Devuelve el valor antes del incremento y luego incrementa _ix. Por lo tanto, la primera vez que llame al método ixAdd en una instancia de myCounter, devolverá 1, la segunda vez devolverá 2, y así sucesivamente.

Cuestiones relacionadas