1.概念

泛型的代码只存在于编译阶段,在进入JVM之前,与泛型相关的信息会被擦除掉,我们称之为类型擦除

2.示例

(1)无限制类型擦除

【Java泛型】类型擦除_开发语言

public class Erasure<T> {

    private T key;

    public T getKey() {
        return key;
    }

    public void setKey(T key) {
        this.key = key;
    }
}

import java.lang.reflect.Field;

public class Demo {
    public static void main(String[] args) {

        Erasure<Integer> erasure = new Erasure<>();
        // 利用反射获取类的字节码文件的Class类对象
        Class<? extends Erasure>  clz = erasure.getClass();
        // 获取所有的成员变量
        Field[] declaredFields = clz.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            // 打印成员变量的名称和类型
            System.out.println(declaredField.getName() + ":" + declaredField.getType().getSimpleName()); // key:Object

        }

    }


}

 (2)有限制类型擦除

【Java泛型】类型擦除_java_02

public class Erasure<T extends Number> {

    private T key;

    public T getKey() {
        return key;
    }

    public void setKey(T key) {
        this.key = key;
    }
}
import java.lang.reflect.Field;

public class Demo {
    public static void main(String[] args) {

        Erasure<Integer> erasure = new Erasure<>();
        // 利用反射获取类的字节码文件的Class类对象
        Class<? extends Erasure>  clz = erasure.getClass();
        // 获取所有的成员变量
        Field[] declaredFields = clz.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            // 打印成员变量的名称和类型
            System.out.println(declaredField.getName() + ":" + declaredField.getType().getSimpleName()); // key:Number

        }

    }


}

(3)擦除方法中类型定义的参数

【Java泛型】类型擦除_类型擦除_03

import java.util.List;

public class Erasure<T extends Number> {

    private T key;

    public T getKey() {
        return key;
    }

    public void setKey(T key) {
        this.key = key;
    }

    /**
     * 泛型方法
     * @param t
     * @param <T>
     * @return
     */
    public <T extends List> T show(T t) {
        return t;
    }
}

import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class Demo {
    public static void main(String[] args) {

        Erasure<Integer> erasure = new Erasure<>();
        // 利用反射获取类的字节码文件的Class类对象
        Class<? extends Erasure>  clz = erasure.getClass();
        // 获取所有的成员变量
        Field[] declaredFields = clz.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            // 打印成员变量的名称和类型
            System.out.println(declaredField.getName() + ":" + declaredField.getType().getSimpleName()); // key:Number

        }


        System.out.println("---------------------------------------------------");

        // 获取所有的方法
        Method[] declaredMethods = clz.getDeclaredMethods();
        for (Method declaredMethod : declaredMethods) {
            // 打印方法名和返回值类型
            System.out.println(declaredMethod.getName() + ":" + declaredMethod.getReturnType().getSimpleName());
        }
        /**
         * getKey:Number
         * show:List
         * setKey:void
         */

    }


}

(4)桥接方法

【Java泛型】类型擦除_开发语言_04

 

/**
 * 泛型接口
 * @param <T>
 */
public interface Info <T>{
    T info(T t);
}
public class InfoImpl implements Info<Integer>{
    @Override
    public Integer info(Integer value) {
        return value;
    }
}