Tipos sin formato en Java

1. Introducción

En este tutorial rápido, veremos los tipos sin formato, qué son y por qué debemos evitarlos.

2. Tipos crudos

Un tipo sin formato es un nombre para una interfaz o clase genérica sin su argumento de tipo:

List list = new ArrayList(); // raw type

En vez de:

List listIntgrs = new ArrayList(); // parameterized type

List es un tipo parametrizado de interfaz List, mientras que List es un tipo sin formato de interfaz List .

Los tipos sin formato pueden ser útiles cuando se interactúa con código heredado no genérico.

De lo contrario, sin embargo, se desaconseja. Esto es porque:

  1. No son expresivos
  2. Carecen de seguridad de tipo y
  3. Los problemas se observan en tiempo de ejecución y no en tiempo de compilación

3. Inexpresivo

Un tipo sin formato no se documenta y se explica a sí mismo de la misma manera que lo hace un tipo parametrizado.

Podemos inferir fácilmente que un tipo List parametrizado es una lista que contiene String s. Sin embargo, un tipo sin formato carece de esta claridad, lo que dificulta trabajar con él y con sus métodos API.

Veamos la firma del método get (int index) en la interfaz List para entender esto mejor:

/** * Returns the element at the specified position in this list. * * @param index index of the element to return * @return the element at the specified position in this list * @throws IndexOutOfBoundsException if the index is out of range * (index = size()) */ E get(int index);

El método get (int index) devuelve una cadena en el índice de posición en el tipo parametrizado List .

Sin embargo, para una lista de tipo sin formato , devuelve un objeto . Por lo tanto, debemos hacer un esfuerzo adicional para inspeccionar e identificar el tipo de elemento en la Lista de tipos sin procesar y agregar una fundición de tipos adecuada. Esto puede introducir errores en tiempo de ejecución, ya que el tipo sin formato no es seguro .

4. No seguro para tipos

Obtenemos comportamiento pre-genérico con tipos sin formato. Por lo tanto, una lista de tipo sin formato acepta Object y puede contener un elemento de cualquier tipo de datos . Esto puede generar problemas de seguridad de tipos cuando mezclamos tipos sin procesar y parametrizados.

Veamos esto creando un código que instancia una List antes de pasarla a un método que acepta List de tipo sin formato y le agrega un Integer :

public void methodA() { List parameterizedList = new ArrayList(); parameterizedList.add("Hello Folks"); methodB(parameterizedList); } public void methodB(List rawList) { // raw type! rawList.add(1); }

El código se compila (con una advertencia) y el Integer se agrega a la Lista de tipos sin procesar cuando se ejecuta. La lista que se pasó como argumento ahora contiene una cadena y un entero .

El compilador imprime una advertencia debido al uso de tipos sin formato:

Note: RawTypeDemo.java uses unchecked or unsafe operations. Note: Recompile with -Xlint:unchecked for details.

5. Problemas en tiempo de ejecución

La falta de seguridad de tipos en un tipo sin formato tiene un efecto causal que puede dar lugar a excepciones en tiempo de ejecución.

Modifiquemos el ejemplo anterior para que el métodoA obtenga el elemento en la posición de índice 1 de nuestra Lista después de llamar al métodoB :

public void methodA() { List parameterizedList = new ArrayList(); parameterizedList.add("Hello Folks"); methodB(parameterizedList); String s = parameterizedList.get(1); } public void methodB(List rawList) { rawList.add(1); }

El código se compila (con la misma advertencia) y lanza una ClassCastException cuando se ejecuta. Esto sucede cuando el método get (int index) devuelve un Integer , que no se puede asignar a una variable de tipo String :

Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String

6. Conclusión

Es difícil trabajar con los tipos sin formato y pueden introducir errores en nuestro código.

Su uso puede tener consecuencias que pueden ser desastrosas y, desafortunadamente, la mayoría de estos desastres ocurren en tiempo de ejecución.

Vea todos los fragmentos de este tutorial en GitHub.