valueof sirve que parse para java integer assert

sirve - string java



¿Por qué se utiliza assert en el método Integer.valueOf de la clase Integer? (4)

Estaba investigando cómo la clase Integer realidad usa objetos en caché, y encontré el siguiente código en el método Integer.valueOf :

public static Integer valueOf(int i) { assert IntegerCache.high >= 127; if (i >= IntegerCache.low && i <= IntegerCache.high) return IntegerCache.cache[i + (-IntegerCache.low)]; return new Integer(i); }

Mi pregunta es:


El caché, normalmente para -128 ... 127, se puede ampliar, lo que podría ser la razón: no debería ser menor. Y como el código funcionaría incluso sin caché, una afirmación podría ser una manera suave: informar sobre un defecto de rendimiento durante el desarrollo. Como afirma, no tienen impacto en el código de producción.


El propósito de las afirmaciones es establecer invariantes y documentar la implementación. Aquí, esta afirmación documenta el hecho de que, cuando se ingresa el método valueOf , se IntegerCache.high valor de IntegerCache.high es al menos 127. Es mejor escribir una afirmación en lugar del comentario, ya que la JVM también verificará la afirmación cuando corresponda. La opción de línea de comando ( -esa ) está activa.

Normalmente esta IntegerCache.high nunca se lanzará, porque IntegerCache.high se inicializa de esta manera:

int h = 127; String integerCacheHighPropValue = sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high"); if (integerCacheHighPropValue != null) { try { int i = parseInt(integerCacheHighPropValue); i = Math.max(i, 127); // Maximum array size is Integer.MAX_VALUE h = Math.min(i, Integer.MAX_VALUE - (-low) -1); } catch( NumberFormatException nfe) { // If the property cannot be parsed into an int, ignore it. } } high = h;

Este código garantiza que el valor será de al menos 127. Por lo tanto, la IntegerCache.high puede arrojarse si modifica IntegerCache.high (utilizando setAccessible(true) y setAccessible(true) ) o si el JDK se modificará en el futuro y el error se introducirá en IntegerCache.high código de inicialización. Por eso existen las afirmaciones: para atrapar bichos.


Mirando a

http://www.docjar.com/html/api/java/lang/Integer.java.html

Veo este comentario

/* * WARNING: This method may be invoked early during VM initialization * before IntegerCache is initialized. Care must be taken to not use * the valueOf method. */

Si hubieran usado valueOf en parseInt entonces, cuando se llama a parseInt al inicio de la inicialización de VM, el valor high sería en realidad cero.

No estoy seguro de qué problemas causaría, pero evidentemente alguien pensó que valía la pena evitarlo.

  1. ¿Cuál es el uso de assert IntegerCache.high> = 127; Leí que aseverar proporciona una forma efectiva de detectar y corregir errores de programación. Pero este es el código de tiempo de ejecución por qué alguien usará aseverar?

Para protegerse contra el código invocado durante la inicialización de la máquina virtual que llama al método valueOf.

  1. ¿Y cuándo lanzará AssertionError en este escenario?

Si ejecuta java con la opción -ea (habilitar aserciones) y hay algún código de inicialización que llama a valueOf, la JVM se bloqueará casi inmediatamente debido a AssertionError. Esperemos que el equipo de Java pruebe esto y arregle el código ofensivo antes de liberarlo.

Contrariamente a las afirmaciones de otras respuestas de que alto siempre será mayor o igual a 128, parece que hay veces en que es cero (sin contar la reflexión).


El JLS exige que el caché de enteros debe estar en su lugar para enteros entre -128 y 127.

En la actualidad, la implementación de Oracle aplica esto pero no más, por lo que el techo de caché podría extenderse en algún momento en el futuro (es poco probable en la práctica, pero estaría completamente en especificaciones).

Sin embargo, nunca puede ser inferior a 127, de lo contrario la implementación ya no se ajustaría a la JLS, y eso sería un gran problema, por lo tanto (creo) por qué la declaración de afirmación está ahí.

Como señaló biziclop en los comentarios, también puede ser modificado por el usuario al pasar un argumento de VM, otra razón (y quizás más convincente) de que la aseveración está en su lugar.

También tenga en cuenta que la declaración de afirmación se omitirá a menos que se ejecute con -ea , por lo que en el uso normal no hay absolutamente ninguna sobrecarga de tiempo de ejecución para esta comprobación.