1、什么是泛型?

泛型(Generics )是把类型参数化,运用于类、接口、方法中,可以通过执行泛型类型调用 分配一个类型,将用分配的具体类型替换泛型类型。然后,所分配的类型将用于限制容器内使用的值,这样就无需进行类型转换,还可以在编译时提供更强的类型检查。

2、泛型有什么用?

泛型主要有两个好处:

(1)消除显示的强制类型转换,提高代码复用

(2)提供更强的类型检查,避免运行时的ClassCastException

3、泛型的使用

类型参数(又称类型变量)用作占位符,指示在运行时为类分配类型。根据需要,可能有一个或多个类型参数,并且可以用于整个类。根据惯例,类型参数是单个大写字母,该字母用于指示所定义的参数类型。下面列出每个用例的标准类型参数:

E:元素

K:键

N:数字

T:类型

V:值

S、U、V 等:多参数情况中的第 2、3、4 个类型

? 表示不确定的java类型(无限制通配符类型)

4、有界泛型

<? extends T>:是指 “ 上界通配符 (Upper Bounds Wildcards) ”

<? super T>:是指 “ 下界通配符 (Lower Bounds Wildcards) ”

—这里有个坑

如 List<? extends T> 大家以为元素为 T以及其所有子类的对象 的List。其实不是。元素类型 仅指T的某一个不确定的子类,是单一的一个不确定类,没有具体哪个类。因此不能插入一个不确定的。

List<? super T> 大家以为元素为 T以及其父类的对象 的List。其实不是,元素类型 仅指T的某一个不确定的父类,是单一的一个不确定类(只确定是T的父类),没有具体哪个类。

因此:

不能往List<? extends T>中插入任何类型的对象。唯一可以保证的是,你可以从中读取到T或者T的子类。

可以往List<? super T>中插入T或者T子类的对象,但不可以插入T父类的对象。可以读取到Object或者Object子类的对象(你并不知道具体的子类是什么)

总结一下:

如果频繁支持读取数据,不要求写数据,使用<? extends T>。即生产者 使用 <? extends T>;

如果频繁支持写入数据,不特别要求读数据,使用<? super T>。即消费者 使用 <? super T>;

如果都需要支持,使用<T>。

5、类型擦除

Java的泛型在编译期间,所有的泛型信息都会被擦除掉。

  • Class c1 = new ArrayList<Integer>().getClass();

    Class c2 = new ArrayList<Long>().getClass();

    System.out.println(c1 == c2);

    这就是 Java 泛型的类型擦除造成的,因为不管是 ArrayList<Integer> 还是 ArrayList<Long>,在编译时都会被编译器擦除成了 ArrayList。Java 之所以要避免在创建泛型实例时而创建新的类,从而避免运行时的过度消耗。

  • 6、泛型类型信息

    那么,如果我们确实某些场景,如HTTP或RPC或jackson需要获取泛型进行序列化反序列化的时候,需要获取泛型类型信息。

    可以参照如下:

  • //获取运行时的泛型类型信息
    public class Test2 { static class ParameterizedTypeReference<T> {
    protected final Type type; public ParameterizedTypeReference() {
    Type superClass = this.getClass().getGenericSuperclass();
    //if (superClass instanceof Class) {
    // throw new IllegalArgumentException(
    //"Internal error: TypeReference constructed without actual type information");
    // } else {
    this.type = ((ParameterizedType) superClass).getActualTypeArguments()[0];
    //}
    } public Type getType() {
    return type;
    }
    } public static void main(String[] args) {
    // System.out.println(new ParameterizedTypeReference<String>().getType());
    // java.lang.ClassCastException: java.lang.Class cannot be cast to java.lang.reflect.ParameterizedType
    // 此处会输出报错,因此ParameterizedTypeReference 应不能直接实例化,可以考虑加abstract System.out.println(new ParameterizedTypeReference<String>() { }.getType());
    // ParameterizedTypeReference 的匿名内部类,可以触发super(),
    //即 ParameterizedTypeReference()的构造器逻辑,正常运行
    } }

      

  • 注意一个关键点:

    可以通过定义类的方式(通常为匿名内部类,因为我们创建这个类只是为了获得泛型信息)在运行时获得泛型参数。

Java 泛型小结的更多相关文章

  1. Java泛型小结

    本来想着写一篇总结Java泛型的文章,但是却发现了一篇不错的博文,引用自: http://www.cnblogs.com/lwbqqyumidi/p/3837629.html#undefined 现摘 ...

  2. Java:泛型基础

    泛型 引入泛型 传统编写的限制: 在Java中一般的类和方法,只能使用具体的类型,要么是基本数据类型,要么是自定义类型.如果要编写可以应用于多种类型的代码,这种刻板的限制就会束缚很多! 解决这种限制的 ...

  3. Java泛型 通配符? extends与super

    Java 泛型 关键字说明 ? 通配符类型 <? extends T> 表示类型的上界,表示参数化类型的可能是T 或是 T的子类 <? super T> 表示类型下界(Java ...

  4. 令人费解的java泛型

         对于我们java中的泛型,可能很多人知道怎么使用并且使用的还不错,但是我认为想要恰到好处的使用泛型,还是需要深入的了解一下它的各种概念和内部原理.本文将尽可能的囊括java泛型中的重要的概念 ...

  5. 解析令人费解的java泛型

    对于我们java中的泛型,可能很多人知道怎么使用并且使用的还不错,但是我认为想要恰到好处的使用泛型,还是需要深入的了解一下它的各种概念和内部原理.本文将尽可能的囊括java泛型中的重要的概念.主要内容 ...

  6. 解析java泛型(一)

    对于我们java中的泛型,可能很多人知道怎么使用并且使用的还不错,但是我认为想要恰到好处的使用泛型,还是需要深入的了解一下它的各种概念和内部原理.本文将尽可能的囊括java泛型中的重要的概念.主要内容 ...

  7. Java——泛型

    前言 一般的类和方法,使用的都是具体的类型:基本类型或者自定义的类.如果我们要编写出适用于多种类型的通用代码,那么肯定就不能使用具体的类型.前面我们介绍过多态,多态算是一种泛化机制,但是也会拘泥于继承 ...

  8. 重读《深入理解Java虚拟机》六、Java泛型 VS C#泛型 (伪泛型 VS 真泛型)

    一.泛型的本质 泛型是参数化类型的应用,操作的数据类型不限定于特定类型,可以根据实际需要设置不同的数据类型,以实现代码复用. 二.Java泛型 Java 泛型是Java1.5新增的特性,JVM并不支持 ...

  9. JAVA泛型中的有界类型(extends super)(转)

    JDK1.5中引入了泛型(Generic)机制.泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数.这种参数类型可以用在类.接口和方法的创建中,分别称为泛型类.泛型接口.泛型方法. Ja ...

随机推荐

  1. [LeetCode&Python] Problem 589. N-ary Tree Preorder Traversal

    Given an n-ary tree, return the preorder traversal of its nodes' values. For example, given a 3-ary  ...

  2. HihoCoder - 1501:风格不统一如何写程序

    时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi写程序时习惯用蛇形命名法(snake case)为变量起名字,即用下划线将单词连接起来,例如:file_name. ...

  3. HDU 4666 最远曼哈顿距离

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4666 关于最远曼哈顿距离的介绍: http://blog.csdn.net/taozifish/ar ...

  4. 《DSP using MATLAB》Problem 4.17

  5. MyBatis 与 Spring Data JPA 选择谁?

    MyBatis 与 Spring Data JPA 选择谁? https://www.v2ex.com/t/285081 jpa predicate优缺点 https://blog.csdn.net/ ...

  6. Assert随笔

    ☆ Assert.notNull(haha, "未找到需要导入的计划1");//haha必须不能为null,if为null则抛出message的异常: Assert.hasText ...

  7. test20181007 wzoi

    题意 分析 考场40分 错误的Manacher+dp. 用\(f(i)\)表示\(s_{1 \sim i}\)的最长偶数回文覆盖长度,在Manacher的同时用刷表法转移,每次还要对\(f(i-1)\ ...

  8. Nolia 给CC添加过滤器

    思路: 1.使用jqurey-tagput ,做得不好看,领导不满意 2.使用bootstrap select2这个控件, 思路: 1.添加css和js的文件 2.添加标签的时候,根据id拼接标签,a ...

  9. Angular 4 父组件调用子组件中的方法

    1. 创建工程 ng new demo3 2. 创建子组件 ng g component child 3. 在子组件中定义方法greeting 4. 父组件html(第三行是模板中调用子组件的方法) ...

  10. python列表中的pop

    pop()将列表指定位置的元素移除,同时可以将移除的元素赋值给某个变量,不填写位置参数则默认删除最后一位. pop()根据键将字典中指定的键值对删除,同时可以将删除的值赋值给变量. a = [1, 2 ...