Solución:
Omitió la solución prevista:
Integer p = Integer.valueOf(1);
Este patrón se conoce como patrón de método de fábrica. Uno puede preguntarse cuál es el beneficio de este método. Afortunadamente, la implementación de class Integer
es de código abierto, así que echemos un vistazo:
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
Parece haber una especie de Integer
-valor de caché. Si uno solicita un Integer
con un valor dentro del rango de caché, Java no crea un nuevo objeto, pero devuelve uno creado previamente. Esto funciona porque Integer
s son inmutables. Incluso se puede controlar el límite de caché superior con la propiedad del sistema java.lang.Integer.IntegerCache.high=...
.
¿Y por qué los otros dos métodos de crear un Integer
generar una advertencia? Porque se establecieron en desuso con Java 9.
Integer#Integer(int value)
:
Obsoleto. Rara vez es apropiado utilizar este constructor. La fábrica estática
valueOf(int)
es generalmente una mejor opción, ya que es probable que produzca un rendimiento de espacio y tiempo significativamente mejor. […]
Integer#Integer(String s)
:
Obsoleto. Rara vez es apropiado utilizar este constructor. Usar
parseInt(String)
para convertir una cadena en unint
primitivo o usovalueOf(String)
para convertir una cadena en unInteger
objeto. […]
Y solo para completar, aquí está la parte para Integer.valueOf(int i)
:
Devuelve un
Integer
instancia que representa el especificadoint
valor. Si un nuevoInteger
No se requiere instancia, este método generalmente se debe usar con preferencia al constructorInteger(int)
, ya que es probable que este método produzca un rendimiento de espacio y tiempo significativamente mejor al almacenar en caché los valores solicitados con frecuencia. Este método siempre almacenará en caché los valores en el rango-128
para127
, inclusive, y puede almacenar en caché otros valores fuera de este rango.
EDITAR 1: Gracias a @VGR por mencionar eso
Integer p = 1;
es equivalente a
Integer p = Integer.valueOf(1);
Esto, sin embargo, solo es cierto para int
-valores entre -128
y 127
. El comportamiento se define en JLS §5.1.7:
[…] Si el valor
p
estar en caja es el resultado de evaluar una expresión constante (§15.28) de tipoboolean
,char
,short
,int
, olong
, y el resultado estrue
,false
, un personaje en el rango'u0000'
para'u007f'
inclusive, o un número entero en el rango-128
para127
inclusivo, entonces dejaa
yb
ser el resultado de dos conversiones de boxeo dep
. Siempre es el caso quea == b
.
EDITAR 2: Gracias a @DorianGray, quien me llamó la atención sobre lo siguiente.
Si bien no está en el JLS, la versión de javac
Estoy usando (9.0.4
) compila el boxeo hasta Integer.valueOf(...);
como se muestra en esta respuesta de Adam Rosenfield.
Método 4, Integer p = Integer.valueOf(1);
es la forma recomendada. El JavaDoc dice:
Devuelve una instancia de Integer que representa el valor int especificado. Si no se requiere una nueva instancia de Integer, este método generalmente debe usarse en lugar del constructor Integer (int), ya que es probable que este método produzca un rendimiento de espacio y tiempo significativamente mejor al almacenar en caché los valores solicitados con frecuencia. Este método siempre almacenará en caché los valores en el rango de -128 a 127, inclusive, y puede almacenar en caché otros valores fuera de este rango.