2012-10-05 15 views
5

¿Realmente necesitamos constantes finales estáticas en Java?Usando métodos que devuelven un valor constante

Supongamos que tengo el siguiente código:

public class Test { 

    public static final int A = 1234; 

    public static int getA() 
    { 
     return 1234; 
    } 
} 

¿Puede usted por favor comparar los dos casos siguientes en términos de eficiencia?

  1. Test.A

  2. Test.getA()

+0

http://codebetter.com/raymondlewallen/2005/07/19/4-mayor-principles-of-object-oriented-programming/ – talnicolas

+0

Tengo curiosidad por saber qué es el bytecode. Un método 'estático' que devuelve una variable' estática final' parece altamente optimizable. – Brian

Respuesta

9

Suponiendo un compilador JIT, no debería haber una diferencia notable en la eficiencia, al menos no lo suficiente como para hacer una diferencia significativa en la velocidad de ejecución de su aplicación.

Sin embargo, hay una notable mejora en la flexibilidad: encapsular el valor en un método casi siempre es bueno, porque le permite cambiar la forma en que se calcula el valor más adelante.

Una excepción notable a esta regla son constantes puras, por ejemplo, del mundo de las matemáticas: no tiene mucho sentido encapsular el acceso a Math.PI, porque no hay posibilidad de que el valor de esta constante fundamental cambie. , lo que provocó la necesidad de cambiar el método de obtener el valor en su programa.

+0

+1 para la ganancia de flexibilidad. – Gamb

+0

Math.PI un buen ejemplo – Jayy

+1

Especialmente porque las referencias a las constantes se copian textualmente al código que las usa, de modo que si una constante cambia, cualquier código que lo use debe recompilarse para obtener el nuevo valor. –

1

En términos de eficiencia, test.getA() menudo se puede reducir hasta el equivalente de test.A por JIT. Aún así, la diferencia sería negligible en el mejor de los casos.

¿Realmente necesitamos constantes estáticas finales en Java?

No, pero ayuda a evitar la asignación repetida.

+0

El JIT optimizará esto, pero esto no es [análisis de escape] (http://docs.oracle.com/javase/7/docs/technotes/guides/vm/performance-enhancements-7.html#escapeAnalysis). – Jesper

+0

@Jesper, después de refrescar mi memoria sobre el tema, creo que tiene razón –

0

La carcasa que muestra es bastante trivial, lo que creo que está destinado. Su primer caso es más directo y eficiente ya que es una llamada menos en la pila, pero creo que un mejor estilo de codificación sería combinar los dos. Supongo que este no será el único lugar donde use esta variable en su clase.

public class Test { 

public static final int A = 1234; 

public static int getA() 
{ 
    return A; 
} 

public static int doSomething() 
{ 
    int result = A * 10; 
    //do more stuff 
    return result; 
} 
} 

Esto le permite sólo para cambiar de variable en un solo lugar si alguna vez necesita un cambio y obtener el resultado esperado a través de su programa. Personalmente, haría privada la int A solo por la coherencia de usar un método get, que es cómo deben configurarse las clases. De esta forma, nunca se encontrará con un problema en el que no pueda recordar si necesita '()' después de acceder al nombre de la variable y todas las variables que viven fuera de la clase de la misma manera. La mayoría de esto es solo estilo de codificación y no correcto o incorrecto.

1

Las variables finales estáticas no se pueden cambiar por código externo, por lo que no es necesario encapsularlas.

Además, un método estático sin parámetros sugiere el acceso al estado de un objeto, que es una mentira, ya que el método es estático.

En cuanto al compilador, no debería haber mucha diferencia en la eficiencia, pero en lo que respecta a la legibilidad del programa y el código de auto-documentación, la final estática es una opción mejor y probada en el tiempo.

2

Las constantes staticfinal se comportan de forma diferente a los valores literales devueltos por un método. El compilador de Java también los usa en ciertos casos en tiempo de compilación.

Un ejemplo,

public static boolean DEBUG = false; 

... 

if (DEBUG) 
{ 
    ...do something... 
} 

vs

public boolean debug() 
{ 
    return false; 
} 

... 

if (debug()) 
{ 
    ...do something 2... 
} 

En el primer caso, la condición y hacer algo ... ... código no será incluido en el byte de código compilado (el archivo de clase). En el segundo caso, la condición y ... hacer algo 2 ... el código se incluirá pero nunca se ejecutará; sin embargo, el JIT puede hacer un análisis suficiente en este caso para eliminar el código en tiempo de ejecución.

En un momento, en los primeros días de Java, el JIT no existía o no era lo suficientemente inteligente como para optimizar el método simple que devuelve un valor literal. Entonces se necesitaba un valor constante para el rendimiento. También es más conveniente definir constantes de esta manera si se tiene en cuenta que las clases externas (para las constantes finales estáticas públicas/protegidas) tendrán el valor incorporado a ese código de bytes en tiempo de compilación; en lugar de obtener el valor de la clase fuente en tiempo de ejecución.

Cuestiones relacionadas