Este artículo pretende poner en valor los cambios más sustanciales realizados en Java desde su versión 8 hasta la actual, Java 17. Estos cambios, bien por importancia, interés o utilidad se han ganado una mención en esta entrada.
Hechas las presentaciones empezamos.
¿Por qué está tan extendido Java 8?
Como programadores hemos pasado por muchos proyectos/clientes y aunque distintos todos ellos cuando nos metemos a código coincidían en algo, la mayoría usaba la misma versión de java, v8.
Esto tiene varios factores que han provocado seguir usando la versión de java de 2014, tales como:
- En su momento algunas herramientas de compilación (Maven, gradle, …) tenían problemas con versiones superiores a Java v8.
- Muchas empresas solo aceptaban las versiones “Long Term Support” más conocidas LTS, esto daba a las empresas la confianza de saber que sería algo duradero en el tiempo (mínimo 3 años).
- Y por último, por esa tendencia que nos acompaña muchas veces “si funciona, no lo cambiamos”.
¿Qué nos aporta la actualización a Java 17?
La actualización de la versión de java nos aporta gran cantidad de mejoras tales como paquetizados más ligeros, compilaciones más rápidas, mejoras de rendimiento, nuevas funcionalidades, código más limpio, compatibilidad con versiones alpine linux lo cual nos facilita su uso en contenedores Docker, ….
Por todo lo mencionado anteriormente y porque es retro compatible (lo que implica que nuestro código, aunque de una versión anterior, seguirá corriendo) la actualización de versiones solo aportará beneficios a los desarrollos.
Novedades destacadas desde Java 8 a Java 17
Nuevas políticas de lanzamientos (Java 9)
Desde que Oracle se hizo cargo cambió la política de sacar versiones grandes cada 3 o 4 años a que se hagan lanzamientos cada 6 meses con pequeñas actualizaciones. Esta política no cambia que se las versiones LTS sigan apareciendo cada 4 años (con la intención que sea cada 2 años).
Nueva palabra reservada “var” (Java 10)
Una de las novedades, a mi parecer, más interesantes es la nueva definición para variable con la palabra reservada “var” siempre que se pueda deducir el tipo, por ejemplo:
public static void main(String arg[]){
var entero = 1;
var cadena = “Testeando”;
var decimal = 1.0;
}
Esto es posible siempre bajo unas condiciones:
Solo se podrán definir dentro de métodos, lo que implica que no podremos usarlo para definir atributos de una clase por ejemplo.
No podemos reasignarlos a tipos distintos.
Anotaciones en Lambdas (Java 11)
Al poder usar var en los argumentos de las operaciones lambdas ahora podemos usar anotaciones en las mismas, por ejemplo:
boolean existeCarro = listaString.stream().anyMatch((@NonNull var s) -> s.equals(“carro”));
Switch como expresión (Java 12)
En versiones anteriores al usar la sentencia switch usábamos un valor dado para evaluar y obtener distintos resultados los cuales podían ser asignados a una variable. Ahora esto puede ser definido como una expresión lo que implica que podemos asignar el “switch” como valor de la variable, dejando así un código más limpio. A continuación, la comparación de cómo queda el código en comparación la versión como expresión.
Así se vería en versiones anteriores:
String tipoLeguaje = ””;
switch (lenguaje){
case “Fortran”:
case “C++”:
case “bankSphere”:
tipoLeguaje = “Old school”;
break;
case “Vue.js”:
case “Java”:
tipoLeguaje = “New age”;
break;
}
System.out.println(tipoLenguaje);
A partir de esta versión podemos dejar un código mas legible
String tipoLeguaje = switch (lenguaje) {
case “Fortran”, “C++”, “bankSphere” -> “Old school”;
case “Vue.js”, “Java” -> “New age”;
}
System.out.println(tipoLenguaje);
Yield en switch (Java 12)
Una ampliación al punto anterior es la palabra “yield” que funcionará a modo return de un método, pudiendo así realizar varias operaciones dentro del switch y devolviendo solo lo que queremos.
String tipoLeguaje = switch (lenguaje) {
case “Fortran”, “C++”, “bankSphere” -> “Old school”;
case “Vue.js”, “Java” -> “New age”;
default -> {
System.out.println(“Desconocido”);
yield “Middle Age”;
}
}
System.out.println(tipoLenguaje);
Nuevos Bloques de texto (Java 13)
Se ha simplificado el tema de los String multi línea pudiendo definirlos de forma más fácil de comprender sin necesidad de concatenación con el símbolo + y unas nuevas comillas por cada línea. Esto ha cambiado y ahora puedes definir un código multi-línea con tan solo 3 comillas dobles, quedando un código limpio y mucho más legible.
En versiones anteriores:
String sql = “SELECT NOMBRE, ” +
“ APELLIDOS, ” +
“ EDAD, ” +
“ DIRECCION, ” +
“ FECHA ” +
“FROM XXXX.PERSONAS ”;
Ahora
String sql = “”” SELECT NOMBRE,
APELLIDOS,
EDAD,
DIRECCION,
FECHA
FROM XXXX.PERSONAS “””;
Records (Java 14)
Los records son tipos de objetos que nos sirven para mover información solamente y que serán inmutables, en ocasiones los veremos definidos como DTO’s o Entities. Cuando queremos cargar un objeto para ser consumido, por ejemplo por un front, tal y como se obtuvo se puede usar esta tipología, sabiendo siempre que son inmutables.
record Persona (String nombre, String mail, int edad){};
Persona p1 = new Persona(“Carlos”, “SolrakRoAl@mail.com”, 25);
// Habiendo definido así la instancia sería imposible ahora hacer una reasignación
p1.nombre = “Cipri”; // ERROR
Instanceof pattern matching (Java 14)
Esto más que un cambio es una mejora ya que en versiones anteriores cuando usábamos instanceof en código y coincidía con algún tipo de las casuísticas indicadas, nos tocaba hacer un casting posterior, siendo esto algo redundante ya que en ese momento ya conocíamos el tipo. Desde ahora este casteo ya no es necesario.
Anteriormente lo usábamos así:
if(obj instanceof Persona) {
Persona p1 = (Persona) obj;
Sistem.out.println(p1.getNombre());
}
Ahora podemos:
if(obj instanceof Persona p1) {
Sistem.out.println(p1.getNombre());
}
Redefinición de herencia (Java 15)
Se ha creado una definición cuando tratamos con herencia de clases que permite limitar qué clases pueden heredar de otra, consiguiendo así un mayor control sobre el código. Un ejemplo de este tipo de herencia controlado sería por ejemplo:
public abstract sealed class Coches
permits Seat, Audi, Renault {....}
En el código anterior estamos limitando quien puede heredar de la clase Coches y solo los indicados serán los que puedan.
Switch e instanceof (Java 17)
Por último una fusión de dos de las novedades ya comentadas anteriormente, con la última versión de java ya podemos usar instanceof con switch.
Como se empezó diciendo no son todos los cambios sino aquellos que se han consideramos más importantes bien por funcionalidad o por utilidad, si queremos profundizar en algún cambio o ver todos los incluidos en cada versión nueva mente podemos consultar este link.