memorándum de java genéricos

1. Antecedentes de los genéricos

En las primeras versiones del lenguaje Java, los elementos del marco de la colección (como List) eran del tipo Object, lo que significaba que cualquier objeto podía almacenarse en la colección. Sin embargo, el uso del tipo de objeto presenta muchos problemas debido a errores de tipo de tiempo de ejecución y código que no se puede mantener. Por lo tanto, para mejorar la seguridad de tipos y la mantenibilidad del código, Java introduce genéricos.

Uno de los objetivos de diseño de los genéricos de Java es mejorar la legibilidad del código. Los genéricos usan parámetros de tipo para reemplazar el tipo de objeto usado en el marco de colección original. Por ejemplo, antes de Java 5, necesitamos crear un ArrayList de tipo String usando:

List names = new ArrayList();
names.add("John");
names.add("Tom");

En este ejemplo, el tipo de elemento en la lista de nombres es Objeto. Esto significa que necesitamos encasillar los elementos de la lista en tiempo de ejecución. Para aplicaciones a gran escala, la lógica de este tipo de conversión puede aparecer en varios lugares del código, lo que aumenta la complejidad y la dificultad de mantenimiento del código. Y después de la aplicación genérica, podemos usar el siguiente código:

List<String> names = new ArrayList<String>();
names.add("John");
names.add("Tom");

En este ejemplo, el tipo de elemento entre corchetes es String, lo que significa que podemos usar de forma segura variables de tipo String en el código sin preocuparnos por los errores de tipo. Esta forma es más intuitiva, más legible y más fácil de mantener.

Por lo tanto, el objetivo de diseño detrás de los genéricos de Java

  • Es para mejorar la legibilidad y mantenibilidad del código , evitar errores tipográficos y reducir el riesgo de errores de código.
  • Además, los genéricos también pueden mejorar la reutilización del código, evitar el código repetido y mejorar la flexibilidad y versatilidad del lenguaje Java.

2. Dónde se pueden usar los genéricos

En Java, los genéricos se pueden aplicar en varios lugares:

  1. El parámetro de tipo se usa en la declaración de clase. Siempre que aparece T en el código de la clase de nombre de tabla, el tipo es el mismo, por ejemplo:
public class MyClass<T> {
    
    
    // generic class
}
  1. Los parámetros de tipo se utilizan en declaraciones de interfaz, por ejemplo:
public interface MyInterface<T> {
    
    
    // generic interface
}
  1. Los parámetros de tipo se utilizan en las declaraciones de métodos, por ejemplo:
public <T> void printList(List<T> list) {
    
    
    // generic method
}

Hay muchos escenarios de uso, y el uso común son las restricciones de límites, como

public <T extends Number> T someFunction(List<T> list) {
    
    
    // 函数体
}

En este ejemplo, el parámetro de tipo T está restringido a ser un subtipo de Número, por lo que se puede usar cualquier implementación de Número en la función.
Para dar otro ejemplo práctico, en este ejemplo se definen dos tipos genéricos R e ID, y estos dos tipos genéricos se pueden usar directamente en el cuerpo del método, lo que mejora la versatilidad del código y lo hace mucho más claro para leer.
/**
* Método de consulta para evitar la penetración de caché
*
* @param keyPrefix
* @param id
* @param type json string deserialized object type
* @param dbFallback función de devolución de llamada, utilizada para consultar la base de datos
* @param time
* @ param unit
* @ param
* @param
* @return
*/
public <R,ID> R queryWithPassThrough(
String keyPrefix, ID id, Class type, Function<ID, R> dbFallback, Long time, TimeUnit unit){ String key = keyPrefix + id; / / 1. Consultar la caché del almacén desde redis String json = stringRedisTemplate.opsForValue().get(key); // 2. Determinar si existe if (StrUtil.isNotBlank(json)) {





// 3. Existe, devuelve directamente
return JSONUtil.toBean(json, type);
}
// Determina si el hit es un valor nulo
if (json != null) { // Devuelve un mensaje de error return null; }


    // 4.不存在,根据id查询数据库
    R r = dbFallback.apply(id);
    // 5.不存在,返回错误
    if (r == null) {
        // 将空值写入redis
        stringRedisTemplate.opsForValue().set(key, "", CACHE_NULL_TTL, TimeUnit.MINUTES);
        // 返回错误信息
        return null;
    }
    // 6.存在,写入redis
    this.set(key, r, time, unit);
    return r;
}
  1. Los parámetros de tipo se utilizan en los constructores, por ejemplo:
public class MyClass<T> {
    
    
    public MyClass(T t) {
    
    
        // generic constructor
    }
}

Nota: Los genéricos no se pueden aplicar directamente a los tipos primitivos, solo a los tipos de referencia. Además, en la especificación del lenguaje Java, el borrado de tipo para genéricos significa que todos los parámetros de tipo genérico se reemplazan con sus límites u Objeto. Por lo tanto, en tiempo de compilación, los argumentos de tipo en la clase o método genérico se borrarán y solo se podrán obtener sus tipos originales en tiempo de ejecución.

Supongo que te gusta

Origin blog.csdn.net/u011624157/article/details/130502599
Recomendado
Clasificación