2012-01-31 9 views
10

considerar esta función:¿Está garantizado el orden de operaciones de izquierda a derecha en Java?

public static final int F(int a, int b) { 
    a = a - 1 + b; 
    // and some stuff 
    return a; 
} 

es lo necesario para las implementaciones de JVM para ejecutar - 1 antes + b?

Si tenemos un analizador de sistema conectado a la JVM, ¿vamos a ver que se está llevando a cabo la operación + b antes de la operación + 1?

+0

No es relevante, pero ¿qué es 'input'? –

+0

@SoboLAN un error tipográfico .. – Pacerier

+1

@Pacerier: este no es un [Ejemplo corto, autónomo, correcto (compilable)] (http://sscce.org). No es autónomo (no hay decadencia de clase, ni principal). No es compilable (contenía un error tipográfico, ¿copió y pegó esto?). –

Respuesta

6

en realidad, voy a estar en desacuerdo con el resto de las respuestas. El JLS §15.7 al que las personas se refieren discute la evaluación de operandos. Es decir, en la expresión

x = foo() - 1 + bar() 

, en cuyo orden se invocarán los métodos.

La sección relevante es §15.7.3, que especifica

Una implementación puede no aprovechar las identidades algebraicas tales como la ley asociativa para reescribir las expresiones de cálculo en un orden más conveniente a menos que se puede demostrar que la expresión de reemplazo es equivalente en valor y en sus efectos secundarios observables [...]

Desde º La expresión e x = x - 1 + q es equivalente en todos los sentidos al x = x + q - 1, una implementación conforme puede reescribir la expresión (si por algún motivo decidiera que es más eficiente).

+0

@Pacerier, tome la siguiente nota. En términos generales, 'foo()' puede afectar a 'bar()', por lo tanto, JVM debe respetar el orden. Lo mismo para 'i> 0 && x/i> 3'. Algebraicamente, 'a && b' es equivalente a' b && a' pero tener 'i> 0' primero evita un NPE en la segunda expresión. – rdllopes

2

Según here:

operadores en la misma línea tienen igual prioridad. Cuando los operadores de igual precedencia aparecen en la misma expresión, una regla debe gobernar que se evalúa primero. Todos los operadores binarios excepto los operadores de asignación se evalúan de izquierda a derecha; Los operadores de asignación se evalúan de derecha a izquierda.

Así que sí.

2

Sí, aunque la gran pregunta es, ¿realmente importa? La resta y la suma tienen la misma precedencia en cualquier operación matemática científica y son conmutables. Es decir:

x = entrada - 1 + q;

es la misma que

x = entrada + q - 1;

+0

Quiero decir que no me gusta cuando se desborda, pero pensando en ello incluso si se desborda, el resultado es el mismo .. – Pacerier

+0

Es cierto, pero de cualquier manera puede obtener el desbordamiento, es decir, si la entrada es MIN_INTEGER oq + entrada = MAX_INTEGER. No hay una forma real de protegerse contra eso en su ejemplo. –

1

Sí, siempre lo hará, a pesar de que no afectaría el resultado de sumar/restar de todos modos.

7

Sí, está en el lenguaje Java specification, §15.7.

El lenguaje de programación Java garantiza que los operandos de los operadores parecen evaluarse en un orden de evaluación específico, es decir, de izquierda a derecha.

Se recomienda que el código no dependa fundamentalmente de esta especificación. El código suele ser más claro cuando cada expresión contiene como máximo un efecto lateral, como su operación más externa, y cuando el código no depende exactamente de qué excepción surge como consecuencia de la evaluación de expresiones de izquierda a derecha.

+0

"Parece ser evaluado": ¿tiene Java una regla "como si", similar a las normas C y C++? A saber, que la JVM tiene permitido hacer lo que quiera, siempre que eso no se distinga del comportamiento de la norma. –

+2

@Rob Sí, lo hace. Puede realizar operaciones en cualquier orden * que aparezca en el hilo de ejecución * como si se realizaran en el orden especificado. Sin embargo, desde el punto de vista de otros hilos, puede parecer que están desordenados. Es por eso que los hilos múltiples deben coordinarse utilizando barreras de memoria bien definidas. – erickson

1

En realidad, no sería la implementación de JVM lo que importa, ya que solo ejecutan una lista de instrucciones del archivo de clase.

2

Puede ver aquí la precedencia del operador en Java: http://bmanolov.free.fr/javaoperators.php.Como + y - tienen la misma precedencia, se ejecutarán en el orden en que aparecen.

Si quieres ser más claro acerca de lo cual la operación se lleva a cabo en primer lugar (o si se quiere romper los incorporada en precedencia) parantheses, puede (y debe) utilizar (( y )), así:

x = (a - b) + (c * (d - e))

1

Me parece que siempre habrá un efecto secundario de la ejecución de X + q - 1 cuando debería estar ejecutando X - 1 + q.

Cuando la suma x + q supera a Bignum en 1, la ejecución de izquierda a derecha tendrá éxito ... La ejecución fuera de servicio generará un desbordamiento.

Por lo tanto, la ejecución fuera de servicio tiene un efecto secundario.

A menos que las capturas de ejecución fuera de servicio se desborden a sí mismas, entonces vuelva a hacer el cálculo en el orden correcto cuando sea necesario para evitar el efecto secundario.

0

Es importante agregar que java tiene prioridad en línea para los operadores que parece basarse en el orden aritmético básico de las operaciones. Para obtener una lista de precedencia completa, consulte este source

Cuestiones relacionadas