基于《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. vue+axios访问本地json数据踩坑点

    当我们想在vue项目中模拟后台接口访问json数据时,我们发现无论如何也访问不到本地的json数据. 注意:1.在vue-cli项目中,我们静态资源只能放在static文件夹中,axios使用get请 ...

  2. 数据库分片(Database Sharding)详解

    本文由云+社区发表 作者:腾讯云数据库 Introduction 导言 任何看到显著增长的应用程序或网站,最终都需要进行扩展,以适应流量的增加.以确保数据安全性和完整性的方式进行扩展,对于数据驱动的应 ...

  3. asp.net core系列 49 Identity 授权(上)

    一.概述 授权是指用户能够访问资源的权限,如页面数据的查看.编辑.新增.删除.导出.下载等权限.ASP.NET Core 授权提供了多种且灵活的方式,包括:Razor pages授权约定.简单授权.R ...

  4. Asp.Net Core 轻松学-多线程之取消令牌

    前言     取消令牌(CancellationToken) 是 .Net Core 中的一项重要功能,正确并合理的使用 CancellationToken 可以让业务达到简化代码.提升服务性能的效果 ...

  5. CSharpGL(53)漫反射辐照度

    CSharpGL(53)漫反射辐照度 本系列将通过翻译(https://learnopengl.com)这个网站上关于PBR的内容来学习PBR(Physically Based Rendering). ...

  6. 《k8s-1.13版本源码分析》-调度器初始化

    源码分析系列文章已经开源到github,地址如下: github:https://github.com/farmer-hutao/k8s-source-code-analysis gitbook:ht ...

  7. 改造断路器集群监控Hystrix Turbine实现自动注册消费者、实时监控多个服务

    在上一篇文章中,我们搭建了Hystrix Dashoard,对指定接口进行监控.但是只能对一个接口进行监听,功能比较局限: Turbine:汇总系统内多个服务的数据并显示到 Hystrix Dashb ...

  8. MongoDB分片群集的部署(用心描述,详细易懂)!!

    概念: MongoDB分片是使用多个服务器存储数据的方法,以支持巨大的数据存储和对数据进行存储 优势: 1.减少了每个分片需啊哟处理的请求数,群集可以提高自己的存储容量和吞吐量 2.减少了每个分片存储 ...

  9. Sql中CHARINDEX用法

    CHARINDEX作用 写SQL语句我们经常需要判断一个字符串中是否包含另一个字符串,但是SQL SERVER中并没有像C#提供了Contains函数,不过SQL SERVER中提供了一个叫CHAEI ...

  10. LeetCode算法题-Toeplitz Matrix(Java实现)

    这是悦乐书的第312次更新,第333篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第181题(顺位题号是766).如果从左上角到右下角的每个对角线具有相同的元素,则矩阵是 ...