基于《Java编程思想》第四版

前言

虽然Java的泛型在语法上和C++相比是类似的,但在实现上两者是全然不同的。

语法

Java只需要一个<>就可定义泛型。在<>中可以使用任意符合Java语法要求的字符作为类型的标识,可以定义泛型类、泛型接口、泛型方法等。

class A<T>{
    T a;

    public <Q> void foo(Q a){

    }
}
interface B<T>{
    void foo(T a);
}

实现

Java的泛型并不像C++那样是在编译时根据需要按照模板实例化对应的类。比如下面这段C++代码,会以A为模板实例化两个类。

template<typename T>
class A
{
public:
    A(){}
    T a;
};
int main()
{
    A<int> a;
    A<float> b;

    return 0;
}

查看汇编可以证实,调用的是两个不同类的构造函数

   0x0000000000400545 <+15>:    callq  0x40056c <A<int>::A()>
   0x0000000000400551 <+27>:    callq  0x400578 <A<float>::A()>

Java中所有类都继承自Object,任意类对象都可以向上转型后,使用Object变量存储其引用。基于这一点,Java的泛型实现时其实只有一种类型。以下两个类实际是等同的

class A<T>{
    T a;
}
class A{
    Object a;
}

当使用反射机制获取泛型类的信息时,可以发现class A<T>实际就是class A

public static void main(String[] args) {
    A<Integer> a = new A();
    Field[] f = a.getClass().getDeclaredFields();
    System.out.println(Arrays.toString(f));
}
// 输出为 [java.lang.Object A.a]

由此我们也可以知道为什么下面这段代码总是输出same class

public static void main(String[] args) {
    A<Integer> a = new A();
    A<Double> b = new A();
    if( a.getClass() == b.getClass() ){
        System.out.println("same class");
    }
}

因为基础类型并不继承自Object,所以Java的泛型是不支持基础类型的。如果这么做了,就会得到一个错误提示Type argument cannot be of primitive type

自限定类型

因为使用泛型时,其类型参数会被当做Object来处理,所以编译器就无法感知真实类型的方法了。
比如下面这段代码,就无法通过编译

class A{
    public void foo(){
        System.out.println("A.foo()");
    }
}

class B<T>{
    T a;
    B(T a){
        this.a = a;
    }
    public bar(){
        a.foo();    // 此处会提示编译错误,Object类型不存在foo()方法
    }
}

此时必须将泛型类B的类型参数做限定,让编译器能从限定中获取到足够的信息去判断类型参数是存在foo()方法的。

class B<T extends A>{
    T a;
    B(T a){
        this.a = a;
    }
    public bar(){
        a.foo();
    }
}

Java学习点滴——泛型的更多相关文章

  1. Java学习之——泛型

    1.概要 generics enable types (classes and interfaces) to be parameters when defining classes, interfac ...

  2. 5 Java学习之 泛型

    1. 基本概念          泛型是Java SE 1.5的新特性,泛型的本质是 参数化类型 ,也就是说所操作的 数据类型 被指定为一个参数.这种参数类型可以用在类.接口和方法的创建中,分别称为 ...

  3. Java学习笔记--泛型

    一个泛型类就是具有一个或者多个类型变量的类. 我们可以只关注泛型,而不会为数据存储的细节而烦恼 . java泛型(一).泛型的基本介绍和使用 http://blog.csdn.net/lonelyro ...

  4. Java学习笔记——泛型

    假定T不仅要指定接口的类继承.使用下面的方式: public class some<T extends Iterable<T> & Comparable<T>&g ...

  5. Java学习点滴——初识Java

    基于<Java编程思想>第四版 前言 "程序就是算法加数据结构",而算法就是控制语句加操作符,编写一个程序就是使用控制语句加操作符去操作数据结构,因此我从Java的控制 ...

  6. JAVA学习之泛型

    ArrayList<E>类定义和ArrayList<Integer>类引用中涉及的术语:1.整个ArrayList<E>称为泛型类型 2.ArrayList< ...

  7. Java学习之泛型和异常

    泛型 1,设计原则或目的:只要代码在编译的时候没有错误,就不会抛异常.  2,泛型通配符  :类型通配符一般是使用 ? 代替具体的类型实参.注意了,此处是类型实参,而不是类型形参!相当于(父类作用)L ...

  8. Java学习之==>泛型

    一.什么是泛型 泛型,即“参数化类型”,在不创建新的类型的情况下,通过泛型指定的不同类型来控制形参具体限制的类型.也就是说在泛型使用过程中,操作的数据类型被指定为一个参数,这种参数类型可以用在类.接口 ...

  9. Java学习_泛型

    什么是泛型. Java标准库提供的ArrayList内部就是一个Object[]数组,配合存储一个当前分配的长度,就可以充当"可变数组". public class ArrayLi ...

随机推荐

  1. H5 新特性之 fileReader 实现本地图片视频资源的预览

    大家好 !!  又见面了, 今天我们来搞一搞   H5的新增API    FileReader     真是一个超级超级方便的API呢!!!很多场景都可以使用.......... 我们先不赘述MDN文 ...

  2. Haskell学习-functor

    原文地址:Haskell学习-functor 什么是Functor functor 就是可以执行map操作的对象,functor就像是附加了语义的表达式,可以用盒子进行比喻.functor 的定义可以 ...

  3. SpringBoot之旅第二篇-配置

    一.引言 虽然springboot帮我们进行了自动配置,但配置还是不可避免的,比如最简单的端口号,数据库连接.但springboot的配置一般不用xml进行配置,而是yml和properties,选择 ...

  4. 『Möbius函数与Möbius反演』

    Möbius函数 定义 设正整数\(n\)算数基本定理分解后为\(n=\prod_{i=1}^{k}p_i^{a_i}\),定义函数 \[ \mu(n)= \begin{cases} 0\ \ (\e ...

  5. Windows下Goland的Terminal设置为Git Bash

    Windows下Terminal默认的使用的是系统自带的cmd,功能实在太少,用起来远不如Git Bash来得方利和高效.其实要在Goland的Terminal中使用Bash设置起来也很简单,设置位置 ...

  6. TensorFlow从1到2(二)续讲从锅炉工到AI专家

    图片样本可视化 原文第四篇中,我们介绍了官方的入门案例MNIST,功能是识别手写的数字0-9.这是一个非常基础的TensorFlow应用,地位相当于通常语言学习的"Hello World!& ...

  7. 『取巧』VS2015试用期过后 继续试用

    背景: 个人电脑 安装的 VS2015 Community 社区版. 一直用得挺好,都忘了要登录. 直到近来,30天试用期过 —— VS弹窗:要登录用户名.密码 才能继续使用. 但是,输入了无数次 邮 ...

  8. UiPath实践经验总结(一)

    用UiPath做RPA也有一段时间了,初上阵不久,遇到过不少大大小小的坑.以下列出一些心得体会,望能抛砖引玉,与同行进行更多交流. 1. 日志策略:将UiPath Robot的Logging Leve ...

  9. vivo4.0系统怎么不ROOT激活Xposed框架的教程

    在越来越多应用室的引流,或业务操作中,大多数需要使用安卓的强大Xposed框架,前几天,我们应用室采购了一批新的vivo4.0系统,大多数都是基于7.0以上系统,大多数不能够刷入Root的su权限,即 ...

  10. Python之路【第六篇】:Python迭代器、生成器、面向过程编程

    阅读目录 一.迭代器 1.迭代的概念 #迭代器即迭代的工具,那什么是迭代呢? #迭代是一个重复的过程,每次重复即一次迭代,并且每次迭代的结果都是下一次迭代的初始值 代码如下: while True: ...