Los genéricos de Java (Generics) son una nueva característica introducida en JDK5 que permite el uso de parámetros de tipo (Type Parameter) al definir clases e interfaces. Los parámetros de tipo declarados se reemplazan con tipos específicos cuando se usan. La aplicación más importante de los genéricos ahora es en el nuevo marco de clases de colección en JDK5, donde se usan Map y List. Las ventajas son evidentes. Podemos extender más clases horizontalmente. Las desventajas son en realidad sus ventajas, porque cuando usamos clases genéricas, debemos tener muy claro el propósito de nuestro código y no podemos usar errores.
La clase genérica más básica.
Copie el código de código de la siguiente manera:
paquete com.garinzhang.javabase.generic.e1;
/**
* La clase genérica más básica, el tipo lo define usted mismo
* @autor Garin Zhang
*
* @param<T>
*/
Punto de clase pública<T> {
var T privada;
pública T getVar() {
devolver var;
}
setVar vacío público (T var) {
this.var = var;
}
}
paquete com.garinzhang.javabase.generic.e1;
clase pública Ejemplo genérico {
/**
* argumentos @param
*/
público estático vacío principal (String [] argumentos) {
Punto<Cadena> p = nuevo Punto<Cadena> ();
p.setVar("codificador");
System.out.println(p.getVar());
}
}
Múltiples tipos genéricos
Copie el código de código de la siguiente manera:
paquete com.garinzhang.javabase.generic.e2;
/**
* Múltiples tipos genéricos Generalmente, es mejor usar letras cercanas a la T, como S, R, etc.
* @autor Garin Zhang
*
* @param<T>
* @param <S>
*/
Bloc de notas de clase pública<T, S> {
clave T privada;
valor S privado;
pública T getKey() {
devolver esta clave;
}
público S getValue() {
devolver este valor;
}
setKey pública vacía (tecla T) {
esta.clave = clave;
}
setValue público vacío (valor S) {
this.value = valor;
}
}
paquete com.garinzhang.javabase.generic.e2;
clase pública Ejemplo genérico {
/**
* argumentos @param
*/
público estático vacío principal (String [] argumentos) {
Bloc de notas<Cadena, Entero> p = nuevo Bloc de notas<Cadena, Entero> ();
p.setKey("codificador");
p.setValue(99999);
System.out.println("clave: " + p.getKey());
System.out.println("valor: " + p.getValue());
}
}
Utilice el comodín "?" en los parámetros del método.
Copie el código de código de la siguiente manera:
paquete com.garinzhang.javabase.generic.e3;
/**
* La clave de este ejemplo está en el método principal.
* @autor Garin Zhang
*
* @param<T>
*/
Información de clase pública<T> {
clave T privada;
pública T getKey() {
devolver esta clave;
}
setKey pública vacía (tecla T) {
esta.clave = clave;
}
@Anular
cadena pública toString() {
devolver this.key.toString();
}
}
paquete com.garinzhang.javabase.generic.e3;
/**
* Utilice comodines en los parámetros del método.
* @autor Garin Zhang
*
*/
clase pública Ejemplo genérico {
/**
* argumentos @param
*/
público estático vacío principal (String [] argumentos) {
Información<Cadena> i = nueva Información<Cadena>();
i.setKey("codificador");
divertido(yo);
Información<Integer> j = nueva Información<Integer>();
j.setKey(9999);
diversión(j);
}
diversión vacía estática pública (Información <?> temp) {
System.out.println("Contenido: " + temperatura);
}
}
La transformación ascendente fracasa
Copie el código de código de la siguiente manera:
paquete com.garinzhang.javabase.generic.e4;
/**
* La clave de este ejemplo está en el método principal.
* @autor Garin Zhang
*
* @param<T>
*/
Información de clase pública<T> {
clave T privada;
pública T getKey() {
devolver esta clave;
}
setKey pública vacía (tecla T) {
esta.clave = clave;
}
@Anular
cadena pública toString() {
devolver this.key.toString();
}
}
paquete com.garinzhang.javabase.generic.e4;
clase pública Ejemplo genérico {
/**
* argumentos @param
*/
público estático vacío principal (String [] argumentos) {
Información<Cadena> strEg = nueva Información<Cadena>();
Información<Objeto> objEg;
// Error de compilación "El tipo no coincide: no se puede convertir de Info<String> a Info<Object>"
//Upcast falló, Cadena -> Objeto
// objEg = strEg;
}
}
El uso de genéricos en interfaces.
Copie el código de código de la siguiente manera:
paquete com.garinzhang.javabase.generic.e5;
/**
* La clave de este ejemplo está en el método principal.
* @autor Garin Zhang
*
* @param<T>
*/
Información de la interfaz<T> {
público T getVar();
}
paquete com.garinzhang.javabase.generic.e5;
/**
* Clase genérica
* @autor Garin Zhang
*
* @param<T>
*/
clase pública InfoImpl<T> implementa Info<T> {
var T privada;
Información públicaImpl(T var) {
this.setVar(var);
}
setVar vacío público (T var) {
this.var = var;
}
pública T getVar() {
devolver este.var;
}
}
paquete com.garinzhang.javabase.generic.e5;
/**
* Clase no genérica
* @autor Garin Zhang
*
* @param<T>
*/
la clase pública InfoImpl1 implementa Info<String> {
var cadena privada;
InfoImpl1 pública (var de cadena) {
this.setVar(var);
}
setVar público vacío (var de cadena) {
this.var = var;
}
cadena pública getVar() {
devolver este.var;
}
}
paquete com.garinzhang.javabase.generic.e5;
clase pública Ejemplo genérico {
/**
* argumentos @param
*/
público estático vacío principal (String [] argumentos) {
Info<String> strEg = new InfoImpl<String>("codificador");
System.out.println("Contenido: " + strEg.getVar());
Info<String> strEg1 = new InfoImpl1("codificador1");
System.out.println("Contenido: " + strEg1.getVar());
}
}
Comodines y el uso de extensiones y super.
Copie el código de código de la siguiente manera:
paquete com.garinzhang.javabase.generic.e6;
/**
* La clave de este ejemplo está en el método principal.
* @autor Garin Zhang
*
* @param<T>
*/
Información de clase pública<T> {
clave T privada;
pública T getKey() {
devolver esta clave;
}
setKey pública vacía (tecla T) {
esta.clave = clave;
}
@Anular
cadena pública toString() {
devolver this.key.toString();
}
}
paquete com.garinzhang.javabase.generic.e6;
clase pública Ejemplo genérico {
/**
* argumentos @param
*/
público estático vacío principal (String [] argumentos) {
Información<Cadena> strEg = nueva Información<Cadena>();
strEg.setKey("codificador");
//Error de compilación "El método fun(Info<? extends Number>) en el tipo GenericExample no es aplicable para los argumentos (Info<String>)"
// upTypeLimit(i);
// Utilice tipos enteros o numéricos.
Información<Integer> intEg = nueva Información<Integer>();
intEg.setKey(9999);
upTypeLimit(intEg);
//Error de compilación "El método downTypeLimit(Info<? super String>) en el tipo GenericExample no es aplicable para los argumentos (Info<Integer>)"
// downTypeLimit(intEg);
// Dado que se usa super, downTypeLimit solo puede recibir la propia Cadena y el Objeto
// Comprobamos la relación de herencia de String, no se heredan otras clases, solo Object
downTypeLimit(strEg);
Información<Objeto> objEg = nueva Información<Objeto>();
objEg.setKey(999);
downTypeLimit(objEg);
}
/**
* <? extiende T> representa el límite superior del tipo, lo que indica que el tipo parametrizado puede ser T o una subclase de T
* @param temp
*/
public static void upTypeLimit(Info<? extiende Número>temp) {
System.out.println("Contenido: " + temperatura);
}
/**
* <? super T> representa el límite inferior del tipo (llamado calificación de supertipo en Java Core), lo que indica que el tipo parametrizado es el supertipo (tipo principal) de este tipo, hasta el objeto.
* En este ejemplo, significa que T solo puede ser Objeto o Cadena, porque Cadena solo hereda de Objeto
* @param temp
*/
vacío estático público downTypeLimit(Info<? super String> temp) {
System.out.println("Contenido: " + temperatura);
}
}
Métodos genéricos, múltiples genéricos en el método.
Copie el código de código de la siguiente manera:
paquete com.garinzhang.javabase.generic.e7;
/**
* Métodos genéricos, múltiples genéricos en el método.
* @autor Garin Zhang
*
* @param<T>
*/
Información de clase pública {
/**
* Formato: modificación del método <lista de tipos separados por comas> nombre del método del tipo de valor de retorno (lista de parámetros)
* Por ejemplo: public <T, S> T fun(T t, S s)
* @param t
* @param s
* @devolver
*/
público <T, S> T divertido(T t, S s) {
System.out.println(s.toString());
devolver t;
}
}
paquete com.garinzhang.javabase.generic.e7;
clase pública Ejemplo genérico {
/**
* argumentos @param
*/
público estático vacío principal (String [] argumentos) {
Información información = nueva información();
String str = info.fun("codificador", "imprimir segundo parámetro genérico");
System.out.println(cadena);
int i = info.fun(30, "imprimir el segundo parámetro nuevamente");
System.out.println(i);
}
}
El tipo genérico pasado o devuelto en el método está determinado por el tipo de parámetro establecido cuando se llama al método.
Copie el código de código de la siguiente manera:
paquete com.garinzhang.javabase.generic.e8;
/**
* se extiende
* @autor Garin Zhang
*
* @param<T>
*/
Información de clase pública<T extiende Número> {
var T privada;
pública T getVar() {
devolver este.var;
}
setVar vacío público (T var) {
this.var = var;
}
@Anular
cadena pública toString() {
devolver this.var.toString();
}
}
paquete com.garinzhang.javabase.generic.e8;
clase pública Ejemplo genérico {
/**
* argumentos @param
*/
público estático vacío principal (String [] argumentos) {
Info<Integer> intEg = fun(30); // Se ha determinado que el tipo aquí es Integer
System.out.println(intEg.getVar());
}
/**
* El tipo genérico pasado o devuelto en el método está determinado por el tipo de parámetro establecido al llamar al método.
* @paramparam
* @devolver
*/
public static <T extiende Número> Información<T> fun(T param) {
Información<T> temp = nueva Información<T>();
temp.setVar(parámetro);
temperatura de retorno;
}
}
Haga que los dos tipos de parámetros pasados en el método sean consistentes
Copie el código de código de la siguiente manera:
paquete com.garinzhang.javabase.generic.e9;
/**
* Ver principal
* @autor Garin Zhang
*
* @param<T>
*/
Información de clase pública<T> {
var T privada;
pública T getVar() {
devolver este.var;
}
setVar vacío público (T var) {
this.var = var;
}
@Anular
cadena pública toString() {
devolver this.var.toString();
}
}
paquete com.garinzhang.javabase.generic.e9;
clase pública Ejemplo genérico {
/**
* argumentos @param
*/
público estático vacío principal (String [] argumentos) {
Información<Cadena> i1 = nueva Información<Cadena>();
i1.setVar("Hola");
Información<Cadena> i2 = nueva Información<Cadena>();
i2.setVar("Codificador");
Información<Entero> i3 = nueva Información<Entero>();
i3.setVar(999);
agregar(i1, i2);
//Error de compilación "El método add(Info<T>, Info<T>) en el tipo GenericExample no es aplicable para los argumentos (Info<String>, Info<Integer>)"
// agregar(i1, i3);
}
/**
* Los dos tipos de parámetros pasados en el método deben ser consistentes
* @paramparam
* @devolver
*/
público estático <T> void add(Info<T> i1, Información<T> i2) {
System.out.println(i1.getVar() + ":" + i2.getVar());
}
}
Genéricos, parámetros variables, similares al objeto Argumentos en JavaScript
Copie el código de código de la siguiente manera:
paquete com.garinzhang.javabase.generic.e10;
clase pública Ejemplo genérico {
/**
* argumentos @param
*/
público estático vacío principal (String [] argumentos) {
Entero i[] = diversión(1, 2, 3, 4, 5, 6);
diversión2(yo);
}
público estático <T> T[] divertido(T... arg) {
devolver argumento;
}
público estático <T> void fun2(T parámetro[]) {
System.out.println("matriz genérica: ");
para(T t : parámetro) {
System.out.println(t + " ,");
}
}
}
Anidamiento genérico: utilice clases genéricas como parámetros para determinar el valor de retorno en función del tipo de valor de retorno;
Copie el código de código de la siguiente manera:
paquete com.garinzhang.javabase.generic.e11;
/**
* Acepta dos tipos genéricos
* @autor Garin Zhang
*
* @param<T>
*/
Información de clase pública<T, V> {
var T privada;
valor V privado;
pública T getVar() {
devolver este.var;
}
setVar vacío público (T var) {
this.var = var;
}
público V getValue(){
devolver este valor;
}
setValue público vacío (valor V) {
this.value = valor;
}
@Anular
cadena pública toString() {
devolver this.var.toString();
}
}
paquete com.garinzhang.javabase.generic.e11;
/**
* Acepta 1 tipo genérico
* @autor Garin Zhang
*
* @param<T>
*/
Demostración de clase pública<S> {
información S privada;
Demostración pública (información S) {
this.setInfo(información);
}
setInfo pública vacía (información S) {
this.info = información;
}
público S getInfo() {
devolver this.info;
}
}
paquete com.garinzhang.javabase.generic.e11;
importar java.util.List;
importar com.google.common.collect.Lists;
clase pública Ejemplo genérico {
/**
* argumentos @param
*/
público estático vacío principal (String [] argumentos) {
Demostración<Info<Cadena, Entero>> d;
Información<Cadena, Entero> i;
i = nueva información<Cadena, Entero>();
i.setVar("Codificador");
i.setValue(999);
d = nueva Demostración<Info<Cadena,Integer>>(i);
System.out.println("Contenido: " + d.getInfo().getVar());
System.out.println("Contenido: " + d.getInfo().getValue());
System.out.println(query(1, 2, 3, 4, 5).toString(); // [1, 2, 3, 4, 5]
// Advertencia "Seguridad de tipos: se crea una matriz genérica de Object&Comparable<?>&Serializable para un parámetro varargs"
System.out.println(query(1, 2, 3, "StringType").toString()); // [1, 2, 3, StringType]
System.out.println(query("Yo", "soy", "un", "codificador").toString());// [Yo, soy, un codificador]
Lista<Cadena> lista = Lists.newArrayList("Yo ", "soy", "un", "codificador");
System.out.println(list.toString()); // [Yo, soy, un codificador]
}
/**
* Determine el tipo genérico a través del valor de retorno. El tipo de valor de retorno en este método se genera automáticamente mediante la definición del método.
* @param elementos
* @devolver
*/
consulta pública estática <E> Lista<E> (E... elementos) {
// https://github.com/exitsoft/exit-web-framework/commit/1d2f1098a2a4b6abab175b793e2308aa8bd0ea16.
//importar com.google.common.collect.Lists;
// <dependencia>
// <groupId>com.google.guava</groupId>
// <artifactId>guayaba</artifactId>
// <versión>16.0.1</versión>
// </dependencia>
devolver Listas.newArrayList(elementos);
}
}