编程思想--第15章--泛型

泛型

一般的类和方法,只能使用具体的类型,要么是基本类型,要么是自定义的类。如果要编写可以应用于多种类型的编码,这种刻板的限制对代码的束缚就会很大。

在面向对象编程语言中,多态算是一种泛化机制。拘泥于单继承体系,会使程序受限太多。有时候使用接口,对程序的约束还是太强。

泛型实现了参数化类型的概念,使代码可以应用于多种类型。最初的目的是希望类或方法能够具备最广泛的表达能力,通过解耦类或方法与所使用的类型之间的约束。

一、与C++的比较

Java中的泛型与C++比较的理由:1,了解C++的局限是什么,为什么会有这些限制。最终的目的是帮助你理解,Java泛型的边界在哪里。2,Java社区中,对C++的误解可能会误导你,令你在理解泛型的意图时产生偏差。

二、简单泛型

泛型出现最引人注目的原因:为了创造容器。泛型的主要目的之一就是用来指定容器要持有什么类型的对象,而且由编译器来保证类型的正确性。

仅一次方法调用就能返回多个对象:将一组对象直接打包存储于其中的一个单一对象,称为元组。这个容器允许读取其中元素,但是不允许向其中存放新对象。元组可以具有任意长度,元组中的对象可以是任意不同的类型。元组隐含地保持了其中元素的次序。

一个堆栈类:LinkedList和Stack

三、泛型接口

泛型也可以应用于接口。例如生成器(generator),这是一种专门负责创建对象的类。一般一个生成器只定义一个方法,该方法用以产生新的对象。实际上,这是工厂方法设计模式的一种应用。当使用生成器创建新的对象时,它不需要任何参数,而工厂方法一般需要参数。也就是说,生成器无需额外的信息就知道如何创建对象。

四、泛型方法

泛型方法使得该方法能够独立于类而产生变化。一个基本的指导原则:无论何时,只要你能做到,就应该只使用泛型方法。

当使用泛型类时,必须在创建对象的时候指定类型参数的值,而使用泛型方法的时候,通常不必指明参数类型,因为编译器会为我们找出具体的类型。这称为参数类型推断。

五、匿名内部类

泛型还可以应用于内部类及匿名内部类。

六、构建复杂模型

泛型的一个重要好处就是能够简单而安全地创建复杂的模型。

七、擦除的神秘之处

在泛型代码内部,无法获得任何有关泛型参数类型的信息。java泛型使用擦除来实现,当你使用泛型时,任何具体的类型信息都被擦除,唯一知道的就是你在使用一个对象。

泛型类型只有在静态烈性检查期间才出现,在此之后,程序中的所有泛型类型都将被擦除,替换为他们的非泛型上界。

擦除和迁移兼容性意味着,使用泛型不是强制的。

因为擦除在方法体中移除了类型信息,所以在运行时的问题就是边界:即对象进入和离开方法的地点。这些正是编译器在编译期执行类型检查并插入转型代码的地点。

八、擦除的补偿

擦除丢失了在泛型代码中执行某些操作的能力,任何情况下运行时需要知道确切类型信息的操作都将无法工作。偶尔可以绕过这些问题来编程,但是有时必须通过引入类型标签来对擦除进行补偿。这意味着你需要显示地传递你的类型的Class对象,以便你可以在类型表达式中使用它。

不能创建泛型数组。一般的 解决方案是在任何想要创建泛型数组的地方都使用ArrayList。

九、边界

边界使得你可以在用于泛型的参数类型上设置限制条件。尽管这使得你可以强制规定泛型可以应用的类型,但是其潜在的一个更重要的效果是你可以按照自己的边界类型来调用方法。

十、通配符

通配符引用的是明确的类型,它意味着某个对象的引用没有指定的具体类型。

超类型通配符可以声明通配符是由某个特定类的任何基类来界定的。

无界通配符 意味着任何事物,无界通配符好像等价于使用原生类型。

十一、问题

任何基本类型都不能作为类型参数。解决之道是使用基本类型的包装器类。

一个类不能实现同一个泛型接口的两种变体,由于擦除的原因,这两个变体会成为相同的接口。

使用带有泛型类型参数的转型或instanceof不会有任何效果。

由于擦除的原因,重载方法将产生相同类型签名。

十二、自限定的类型

不能直接继承一个泛型参数,但是可以继承在其自己的定义中使用这个泛型参数的类。自限定的参数可以保证类型参数必须与正在被定义的类相同。如果使用自限定,就应该了解这个类所用的类型参数将与使用这个参数的类具有相同的基类型。这会强制要求使用这个类的每个人强制遵循这种形式。

自限定类型的价值在于它们可以产生协变参数类型--方法参数类型会随子类而变化。

十三、动态类型安全

泛型容器的旧式代码仍旧可能会破坏你的容器,类型检查问题可以用java.util.Collections的静态方法CheckedCollection(),checkedList(),checkedMap(),checkedSet(),checkedSortedMap()和checkedSortedSet().这些方法每一个都会将你希望动态检查的容器当做第一个参数接受,并将你希望强制要求的类型作为第二参数接受。

十四、异常

由于擦除原因,将泛型应用于异常是非常受限的。catch语句不能捕获泛型类型的异常,因为在编译时期和运行时期都必须知道异常的确切类型。反射类也不能直接或间接继承自Throwable。但是类型参数可能会在一个方法的throws字句中用到,这使得

你可以编写随检查型异常的类型二发生变化的泛型代码。如果不能参数化所抛出的异常,由于检查型异常的缘故,不能编写出这种泛化的代码。

十五、混型

混型概念是混合多个类的能力,以产生一个可以表示混型中所有类型的类,它将使组装多个类变得简单易行。

混型的价值之一是它们可以将特性和行为一致地应用于多个类之上。如果想在混型类中修改某些东西,作为一种意外的好处,这些修改将会应用于混型所应用的所有类型之上。

与接口混合:使用接口来产生混型效果。

使用装饰器模式:装饰器使用分层对象来动态透明地向单个对象中添加责任。装饰器通过使用组合和形式化结构来实现,而混型是基于继承。

与动态代理混合:通过使用动态代理,所产生的类的动态类型将会是已经混入的组合类型,由于动态代理的限制,每个被混入的类都必须是某个接口的实现。

十六、潜在类型机制

潜在类型机制是一种代码组织和复用机制。有了它编写出的代码相对于与没有它写出的代码,能够更容易地复用。

十七、对缺乏潜在类型机制的补偿

java不支持潜在类型机制,但是这并不意味着有界泛型代码不能再不同的类型层次结构之间应用。我们仍旧可以创建真正的泛型代码,但是这需要一些额外的努力。

反射:通过反射能够动态地确定所需要的方法收可用并调用它们。他甚至能够处理Mime只具有一个必需的方法这一事实,并能够部分实现其目标。

将一个方法应用于序列:反射提供了一些有趣的可能性,但是它将所有的类型检查都转移奥了运行时。如果能够实现编译器类型检查,这通常会更符合要求。

十八、将函数对象用作策略

使用策略设计模式,可以产生更优雅的代码,它将变化的事物完全隔离到了一个函数对象中。

函数对象的价值在于,与普通方法不同,它们可以传递出去,并且还可以拥有在多个调用之间持久化的状态。

十九、总结:转型真的如此之糟吗?

使用泛型类型机制的最吸引人的地方,就是在使用容器类的地方,这些类包括各种List,Set,Map等中。

泛型的通用语言特性的目的在于可表达性,而不仅仅是为了创建类型安全的容器。类型安全的容器是能够创建更通用代码这一能力所带来的副作用。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 221,198评论 6 514
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,334评论 3 398
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 167,643评论 0 360
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,495评论 1 296
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,502评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,156评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,743评论 3 421
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,659评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,200评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,282评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,424评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,107评论 5 349
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,789评论 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,264评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,390评论 1 271
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,798评论 3 376
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,435评论 2 359

推荐阅读更多精彩内容