Genéricos (borrado genérico, se pueden reflejar los genéricos, limitaciones y problemas de los genéricos)

1. Borrado genérico

泛型的擦除是是用一种称为类型消除( type erasure)的方法来实现的。
当泛型存在于编译时,一旦被确认安全使用时,
就会将其转换为原生类型也就是擦除成原生类型。

泛型擦除是指泛型代码在编译后,都会被擦除为原生类型。例如
Zoo<Fish>和Zoo<Bird>,实际上在运行时都是同一种类型,即
原生类型Zoo。这就意味着运行时,Java并不存在类型参数这一概念,
因此将无法任何相关的参数类型信息。

例如下面的代码证实了泛型擦除:
package Generic.wildcardsAndBoundaries;

public class Test {
    
    
    public static void main(String[] args) {
    
    
        Zoo<Fish> fishZoo = new Zoo<>(new Fish());
        Zoo<Bird> birdZoo = new Zoo<>(new Bird());
        System.out.println("两者的类型相同吗? " + fishZoo.getClass().equals(birdZoo.getClass()));
    }
}

resultado de la operación:
Inserte la descripción de la imagen aquí


1.1 Por qué borrar los genéricos

擦除是java泛型方法实现的一种折中办法。
因为擦除的核心动机是使得泛化的代码可以使用非泛化的类库,
反之亦然,为了让非泛型的代码和泛型的代码共存,实现擦除非常可靠!

1.2 Cómo borrar

其实擦除的实质就是将原有的类型参数替换成即非泛化的上界。如:
public class Computer<E> {
    
    
    private E e;
    public Cmputer(E e){
    
    
        this.e=e;
    }
    public E apply(){
    
    
        return this.e;
    }
}
上方代码经过编译后,将被编译成以下代码形式:
public class Computer {
    
    
    private Object e;

    public Computer(Object e) {
    
    
        this.e = e;
    }

    public Object apply() {
    
    
        return e;
    }
}
通过比较你会发现原有类型参数消失了,取而代之为参数类型Object,
这是因为Computer<E>没有指明上界,编译器将其自动擦除成顶类Object类型

若指明了上界如<E extends electrical>,则会有如下翻译:

Inserte la descripción de la imagen aquí


1.3 Borrado de bordes múltiples

Inserte la descripción de la imagen aquí


2 Los genéricos pueden reflejar

Inserte la descripción de la imagen aquí


3 Restricciones y problemas de los genéricos

因为擦除机制使得运行时丢失了泛型信息,
因此一些理所当然的功能在java泛型系统中得不到支持。
  • Restricción 1:
    para garantizar la seguridad de los tipos, no puede utilizar parámetros de tipos genéricos para crear instancias
    // objeto T ilegal = new T ();
  • Limitación 2:
    No puede declarar una matriz de instancia genérica, lo que provocará errores en tiempo de ejecución.
    // T [] números ilegales = nueva T [capcity];
    pero puede evitar esto creando una matriz de tipo de objeto y convirtiendo su tipo a E [] límite.
    T [] número = (E []) nuevo objeto [capcity]:
  • Restricción 3:
    en un entorno estático, no se permite que el tipo de parámetro sea un tipo genérico. (Debido a que todas las instancias de una clase genérica tienen la misma clase en tiempo de ejecución, las variables estáticas y los métodos de una clase genérica son compartidos por todas sus instancias. Dado que son compartidos, no es necesario que redefina el mismo tipo genérico, si no lo hace No define el mismo tipo genérico y no puede lograr compartir (o consistencia), no hay necesidad de dejar pasar esta situación. Por lo tanto, en un entorno estático, el parámetro de la clase se establece en el tipo genérico. Ilegal).
  • Limitación 4:
    Los objetos de clase genérica no se pueden lanzar ni capturar, porque las clases genéricas no pueden heredar o implementar la interfaz Throwable y sus subclases.

Supongo que te gusta

Origin blog.csdn.net/I_r_o_n_M_a_n/article/details/115203473
Recomendado
Clasificación