Tipos genéricos

Un tipo genérico es una clase o interfaz genérica que se parametriza sobre tipos. La siguiente clase Box se modificará para demostrar el concepto.

Una clase Box simple

Empiece por examinar una clase Box no genérica que opere en objetos de cualquier tipo. Solo necesita proporcionar dos métodos: set, que agrega un objeto al cuadro, y get, que lo recupera:

Dado que sus métodos aceptan o devuelven un objeto, puede pasar lo que quiera , siempre que no sea uno de los tipos primitivos. No hay forma de verificar, en tiempo de compilación, cómo se usa la clase. Una parte del código puede colocar un número entero en el cuadro y esperar obtener números enteros de él, mientras que otra parte del código puede pasar por error una cadena, lo que resulta en un error de tiempo de ejecución.

Una versión genérica de la clase Box

Una clase genérica se define con el siguiente formato:

class name<T1, T2, ..., Tn> { /* ... */ }

Para actualizar el Clase de caja para usar genéricos, crea una declaración de tipo genérico cambiando el código «caja de clase pública» a «caja de clase pública =» 4cf13a6cbc «> T > «. Esto introduce la variable de tipo, T, que se puede usar en cualquier lugar dentro de la clase.

Con este cambio, la clase Box se convierte en:

Como puede ver, todas las apariciones de Object son reemplazada por T.Una variable de tipo puede ser cualquier tipo no primitivo que especifique: cualquier tipo de clase, cualquier tipo de interfaz, cualquier tipo de matriz o incluso otra variable de tipo.

Esta misma técnica se puede aplicar para crear interfaces genéricas.

Convenciones de nomenclatura de parámetros de tipo

Por convención, los nombres de parámetros de tipo son letras simples en mayúsculas. Esto contrasta fuertemente con las convenciones de nomenclatura de variables que ya conoce, y por una buena razón: sin esta convención, sería difícil distinguir entre una variable de tipo y un nombre de clase o interfaz ordinario.

Los nombres de parámetros de tipo más comúnmente utilizados son:

  • E – Elemento (utilizado ampliamente por Java Collections Framework)
  • K – Key
  • N – Número
  • T – Tipo
  • V – Valor
  • S, U, V, etc. – 2. °, 3. °, 4. ° tipos

Verá estos nombres usados en la API de Java SE y en el resto de esta lección.

Invocación e instanciación de un tipo genérico

Para hacer referencia a la clase Box genérica desde dentro de su código, debe realizar una invocación de tipo genérico, que reemplaza T con algún valor concreto, como Integer:

Box<Integer> integerBox;

Puede pensar en una invocación de tipo genérico similar a una invocación de método ordinario, pero en lugar de pasar un argumento a am método, está pasando un argumento de tipo (Integer en este caso) a la clase Box en sí.

Terminología de parámetro de tipo y argumento de tipo: muchos desarrolladores usan los términos «parámetro de tipo» y «argumento de tipo» indistintamente pero estos términos no son los mismos. Al codificar, se proporcionan argumentos de tipo para crear un tipo parametrizado. Por lo tanto, la T en Foo < T > es un parámetro de tipo y la Cadena en Foo < String > f es un argumento de tipo. Esta lección observa esta definición al usar estos términos.

Como cualquier otra declaración de variable, este código en realidad no crea un nuevo objeto Box. Simplemente declara que integerBox contendrá una referencia a una «Caja de entero», que es como se lee Box < Integer >.

Una invocación de un tipo genérico generalmente se conoce como tipo parametrizado.

Para crear una instancia de esta clase, use la nueva palabra clave, como de costumbre, pero coloque < Entero > entre el nombre de la clase y el paréntesis:

Box<Integer> integerBox = new Box<Integer>();

The Diamond

En Java SE 7 y versiones posteriores, puede reemplazar los argumentos de tipo necesarios para invocar el constructor de una clase genérica con un conjunto vacío de argumentos de tipo (< >) siempre que el compilador pueda determinar, o inferir, los argumentos de tipo del contexto. Este par de corchetes angulares, < >, se llama informalmente el diamante. Por ejemplo, puede crear una instancia de Box < Integer > con la siguiente declaración:

Box<Integer> integerBox = new Box<>();

Para obtener más información sobre la notación de diamantes y la inferencia de tipos, consulte Inferencia de tipos.

Parámetros de tipos múltiples

Como se mencionó anteriormente, una clase genérica puede tener varios parámetros de tipo.Por ejemplo, la clase OrderedPair genérica, que implementa la interfaz Par genérica:

Las siguientes declaraciones crean dos instancias de la clase OrderedPair:

El código, new OrderedPair < String, Integer >, instancia K como String y V como Integer. Por lo tanto, los tipos de parámetros del constructor de OrderedPair son String e Integer, respectivamente. Debido al autoboxing, es válido pasar un String y un int a la clase.

Como se menciona en The Diamond, debido a que un El compilador de Java puede inferir los tipos K y V de la declaración OrderedPair < String, Integer >, estas declaraciones se pueden abreviar usando notación de diamante:

OrderedPair<String, Integer> p1 = new OrderedPair<>("Even", 8);OrderedPair<String, String> p2 = new OrderedPair<>("hello", "world");

Para crear una interfaz genérica, siga las mismas convenciones que para crear una clase genérica.

Tipos parametrizados

OrderedPair<String, Box<Integer>> p = new OrderedPair<>("primes", new Box<Integer>(...));

Write a Comment

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *