Consigna y alcance
Su equipo está evaluando la función en vista previa (preview feature) de Java 25 para patrones de tipos primitivos en instanceof, switch y patrones de records. El código recibe valores Number de un parser y debe clasificar casos de enteros y de punto flotante sin reducciones accidentales ni fallos por null. Explique las reglas del lenguaje, escriba un ejemplo breve y proporcione una decisión de compatibilidad y despliegue.
JEP 507 es una función en vista previa en Java 25. Una buena respuesta debe señalar que la sintaxis de vista previa requiere flags explícitos de compilador y de tiempo de ejecución, y no constituye automáticamente un contrato de producción estable.
Qué evalúa el entrevistador
- Si distingue entre patrones de referencia, patrones primitivos y conversiones de boxing.
- Si puede explicar la ampliación segura (widening), la reducción no segura (narrowing) y la pérdida de información.
- Si maneja explícitamente
null,NaN, infinito y tipos de selector. - Si comprende el comportamiento exhaustivo de switch y el límite de compatibilidad de las funciones en vista previa.
- Si puede diseñar pruebas y una alternativa de respaldo en lugar de adoptar sintaxis solo porque parece más corta.
El entrevistador busca reglas y contraejemplos, no una lista de números de JEP.
Aclaraciones que conviene hacer primero
- ¿El build tiene permitido usar funciones de vista previa en CI y producción? De lo contrario, la solución debe utilizar patrones de la era de Java 21 o conversiones explícitas.
- ¿“Clasificar un número” conserva el valor original o es aceptable un resultado entero acotado? Eso cambia si la reducción es válida.
- ¿
nulldebe rechazarse, mapearse aUNKNOWNo manejarse en una rama dedicada del switch? - ¿Son válidos como entrada
NaNy los infinitos? El emparejamiento de tipos numéricos no los convierte en valores finitos ordinarios. - ¿El mismo código fuente debe compilar en un JDK sin vista previa? En caso afirmativo, aísle el código de vista previa tras un módulo o mantenga una implementación estable.
Estructura para una respuesta de 30 segundos
“La vista previa de JEP 507 en Java 25 permite que los patrones mencionen tipos primitivos en contextos que antes requerían boxing o guardas complejas. El compilador permite conversiones que son seguras bajo las reglas de patrones y rechaza la reducción que pueda perder información. Yo manejaría null antes de la coincidencia de primitivos, probaría valores límite como Integer.MAX_VALUE, NaN e infinito, y mantendría el flag de vista previa en la cadena de herramientas. Si el despliegue no puede fijar Java 25 con vista previa habilitada, usaría un switch estable o una conversión explícita y validada en su lugar.”
Solución paso a paso
1. Comenzar con el tipo estático del valor
La compatibilidad de patrones no es una licencia para convertir cualquier número en cualquier primitivo. Una referencia Number puede contener un Integer, Long, Double u otra implementación. Un patrón que primero reconoce un wrapper de referencia y luego hace unboxing mantiene un contrato diferente al de un patrón de tipo primitivo sobre un selector primitivo. Indique el tipo de selector y la dirección de la conversión antes de discutir la exhaustividad.
static String classify(Number value) {
if (value == null) {
return "missing";
}
return switch (value) {
case Integer i -> "int:" + i;
case Long l -> "long:" + l;
case Double d when Double.isNaN(d) -> "nan";
case Double d -> "double:" + d;
default -> "other";
};
}Este ejemplo estable coincide con tipos wrapper. No afirma que cada Number pueda reducirse de forma segura a int.
2. Explicar la ampliación frente a la reducción
JEP 507 regulariza los patrones primitivos para que un patrón pueda coincidir con un valor primitivo cuando la conversión sea segura para la variable del patrón. Ampliar un int a long preserva todos los valores. Reducir un long a int puede descartar bits altos, por lo que un patrón que acepte silenciosamente dicha conversión es inseguro. La respuesta debe nombrar la conversión rechazada y proponer una verificación de rango explícita si la reducción es un requisito del negocio.
static String bucket(long value) {
if (value >= Integer.MIN_VALUE && value <= Integer.MAX_VALUE) {
int narrowed = (int) value;
return "small:" + narrowed;
}
return "wide:" + value;
}El cast ahora está protegido por una invariante visible. Un patrón no sustituye esa comprobación.
3. Separar null de la coincidencia de tipos primitivos
Los valores primitivos no pueden ser null, pero un selector con boxing sí. Un switch sobre un selector de referencia no convierte silenciosamente a null en un caso numérico. Agregue case null cuando el dominio requiera un resultado total, o rechácelo antes del switch. No use una rama default para ocultar un null inesperado o un wrapper desconocido; esos casos tienen respuestas operativas diferentes.
Para valores de punto flotante, coincidir con un tipo double no significa que el valor sea finito. Mantenga comprobaciones explícitas para NaN, infinito positivo e infinito negativo cuando el código posterior asuma ordenamiento o aritmética.
4. Construir un switch exhaustivo deliberadamente
Los patrones primitivos y las constantes pueden hacer que un switch sea conciso, pero la cobertura sigue dependiendo del dominio del selector y de las guardas. Un caso con guarda no cubre todos los valores de su tipo. Use un caso sin guarda o default para el resto, e incluya case null para selectores que acepten null. Si el switch devuelve un valor utilizado para facturación, análisis o políticas de seguridad, haga que el caso de respaldo sea observable en lugar de aceptarlo silenciosamente.
5. Verificar los límites de la vista previa
JEP 507 es una vista previa en Java 25. La compilación y la ejecución necesitan la opción --enable-preview correspondiente, y la versión source/target debe coincidir con el JDK seleccionado. La sintaxis en vista previa puede cambiar o desaparecer en una versión posterior. CI también debería compilar una alternativa de respaldo estable, y un artefacto debería registrar el JDK, el flag de vista previa y el nivel de lenguaje. Una biblioteca debería evitar obligar a los consumidores a habilitar la vista previa simplemente para invocar una API pública.
6. Comparar alternativas
Use patrones explícitos de wrappers cuando la entrada sea un Number heterogéneo y la compatibilidad importe. Use un switch primitivo cuando el selector ya sea un primitivo y el despliegue pueda fijar la cadena de herramientas de vista previa. Use una conversión validada cuando la regla de negocio sea “ajustar en 32 bits”, porque la verificación de rango comunica la intención y sobrevive a un cambio de sintaxis. Un código fuente más corto no es prueba de un contrato numérico más seguro.
Respuesta de ejemplo de alta calidad
“Primero establecería el selector y la política de null. JEP 507 de Java 25 es una función en vista previa, por lo que no la presentaría como sintaxis estable. Los patrones primitivos permiten un emparejamiento más seguro y uniforme a través de instanceof, switch y patrones de records, pero no hacen que la reducción sea sin pérdidas. Ampliar un int a long preserva los valores; convertir un long a int necesita una comprobación de rango explícita. Para entradas con boxing manejo null, distingo los tipos wrapper y clasifico por separado NaN e infinito. Cada switch tiene un resto intencional, y los casos con guarda no proporcionan cobertura total. Si producción no puede fijar Java 25 con vista previa habilitada, mantengo patrones de wrappers o verificaciones explícitas y compilo ambas rutas en CI. Las pruebas incluyen null, cada límite numérico, representaciones duplicadas, NaN, infinito y una compilación sin vista previa.”
Errores comunes
- Llamar estable a la sintaxis de vista previa → un JDK posterior puede cambiarla o eliminarla → fije el JDK y mantenga una alternativa de respaldo.
- Asumir que toda conversión numérica es segura → la reducción puede perder bits o rechazar valores → declare la conversión y demuestre su rango.
- Dejar que
defaultabsorba null → null y los tipos desconocidos necesitan un manejo diferente → agreguecase nullo rechace antes de la coincidencia. - Tratar una coincidencia con
doublecomo finita →NaNy el infinito siguen satisfaciendo el tipo primitivo → pruébelos y clasifíquelos explícitamente. - Usar un caso con guarda como exhaustivo → los valores que no cumplen la guarda quedan sin coincidencia → agregue un resto sin guarda y pruebe la cobertura.
Preguntas de seguimiento y respuestas
¿Puede un patrón long vincular de forma segura un selector int?
Sí, la ampliación preserva el valor de int. La dirección opuesta no es segura por lo general, ya que un long puede exceder el rango de int. Si el dominio garantiza un límite, codifique la verificación explícitamente y pruebe ambos extremos.
¿Por qué no simplemente aplicar boxing a cada valor?
El boxing puede facilitar la inspección de entradas heterogéneas, pero agrega asignación de memoria y semántica de wrappers, y no demuestra que una conversión preserve el valor. Elíjalo por compatibilidad de API, no como una forma de eludir el razonamiento numérico.
¿Cómo probaría la implementación en vista previa?
Ejecute los mismos casos contra la implementación de vista previa y la alternativa estable: null, cero, valores mínimos y máximos, valores fuera de rango por uno, NaN, ambos infinitos, wrappers desconocidos, fallos de casos con guarda y entradas mal formadas. Compile con los flags exactos de release y preview en CI, luego ejecute un job de compatibilidad sin vista previa.
¿Qué pasa si Java 26 cambia las reglas de la vista previa?
Trate el nivel del lenguaje como parte del contrato del artefacto. Lea las nuevas notas de la versión, compile la rama candidata, compare la semántica con las pruebas de la alternativa de respaldo y promueva solo después de que la matriz de código fuente y entorno de ejecución sea exitosa. No habilite silenciosamente un nuevo flag de vista previa en producción.