什么是泛型,为什么要使用泛型? 泛型类和泛型方法的实现以及限定通配符的使用。什么是泛型擦除,为什么有泛型擦除,泛型擦除到底是怎么实现的

1. 泛型的定义和意义

1.1 什么叫泛型?

泛型,顾名思义就是广泛的类型,专业术语为“参数化类型”;当我们创建对象时没指定类型,任何引用类型都可以使用,兼容多种数据类型。如果是基本类型,会自动装箱转为对应的包装类,如下图。

什么是泛型,为什么要使用泛型? 泛型类和泛型方法的实现以及限定通配符的使用。什么是泛型擦除,为什么有泛型擦除,泛型擦除到底是怎么实现的_第1张图片

1.2 但是指定类型后,只能使用特定类型,如下图。

什么是泛型,为什么要使用泛型? 泛型类和泛型方法的实现以及限定通配符的使用。什么是泛型擦除,为什么有泛型擦除,泛型擦除到底是怎么实现的_第2张图片

1.3 为什么要使用泛型?

因为对于一些工具类来说,编写时是不知道使用者到时用在哪些类上,所以为了能够自适应类型,就得使用泛型这种机制。

2. 泛型的使用和工作原理

2.1 泛型类的定义及使用

什么是泛型,为什么要使用泛型? 泛型类和泛型方法的实现以及限定通配符的使用。什么是泛型擦除,为什么有泛型擦除,泛型擦除到底是怎么实现的_第3张图片

2.2 泛型方法的定义及使用

什么是泛型,为什么要使用泛型? 泛型类和泛型方法的实现以及限定通配符的使用。什么是泛型擦除,为什么有泛型擦除,泛型擦除到底是怎么实现的_第4张图片

2.3 工作原理

事实上,泛型只在编译阶段有作用,编译器检验泛型信息之后,如果没有限定类型,那么泛型的相应使用处会替换为Object类型。如果限定了类型,那么在使用时会先进行类型检查,然后会进行类型擦除源代码和字节码文件反编译分析如下图。

什么是泛型,为什么要使用泛型? 泛型类和泛型方法的实现以及限定通配符的使用。什么是泛型擦除,为什么有泛型擦除,泛型擦除到底是怎么实现的_第5张图片

什么是泛型,为什么要使用泛型? 泛型类和泛型方法的实现以及限定通配符的使用。什么是泛型擦除,为什么有泛型擦除,泛型擦除到底是怎么实现的_第6张图片    什么是泛型,为什么要使用泛型? 泛型类和泛型方法的实现以及限定通配符的使用。什么是泛型擦除,为什么有泛型擦除,泛型擦除到底是怎么实现的_第7张图片

什么是泛型,为什么要使用泛型? 泛型类和泛型方法的实现以及限定通配符的使用。什么是泛型擦除,为什么有泛型擦除,泛型擦除到底是怎么实现的_第8张图片

 什么是泛型,为什么要使用泛型? 泛型类和泛型方法的实现以及限定通配符的使用。什么是泛型擦除,为什么有泛型擦除,泛型擦除到底是怎么实现的_第9张图片   什么是泛型,为什么要使用泛型? 泛型类和泛型方法的实现以及限定通配符的使用。什么是泛型擦除,为什么有泛型擦除,泛型擦除到底是怎么实现的_第10张图片

通过上面的代码分析,我们实现了泛型擦除并且知道泛型擦除是什么。泛型擦除就是在擦除前,如果指定了类型,那么使用时会进行类型检查,然后在编译后进行泛型擦除,字节码中已经不存在泛型,泛型相应使用处都使用Object替代。

什么是泛型,为什么要使用泛型? 泛型类和泛型方法的实现以及限定通配符的使用。什么是泛型擦除,为什么有泛型擦除,泛型擦除到底是怎么实现的_第11张图片

那么类型擦除的作用是什么呢? 是为了确保和没有泛型特性的JDK5版本的类库兼容。

3. 限定通配符和非限定通配符 

3.1 限定通配符

限定通配符有两种:一种是,通过这种确保泛型是T的子类,可以是T本身,也可以是子类的子类,这样的话,T的多个实现类都可以作为泛型对象;另一种是,通过确保类型必须是T的父类来设定类型的下界。

3.2 非限定通配符

非限定通配符即,可以是任何类型,但是它不可以定义类和泛型方法,一般用作参数,如下图。

什么是泛型,为什么要使用泛型? 泛型类和泛型方法的实现以及限定通配符的使用。什么是泛型擦除,为什么有泛型擦除,泛型擦除到底是怎么实现的_第12张图片

附录:代码

public class GenericTest {
    public static void main(String[] args) {
        GenericClass genericClass = new GenericClass();
        String s = "abc";
        genericClass.test(s);

        testGe(s);
    }

    public static   T testGe(T t){
        if(t instanceof String){
            System.out.println("String: " + t);
        }else if(t instanceof Integer){
            System.out.println("Integer: " + ((Integer)t + 1));
        }
        return t;
    }
}

class GenericClass {
    T test(T t){
        System.out.println("泛型类测试");
        return t;
    }
}

你可能感兴趣的:(Java,限定通配符和非限定通配符,泛型类和泛型方法,什么是泛型擦除)