JAVA 泛型意淫之旅(一)

  • 泛型基础
  • 自定义泛型
    • 自定义泛型类型
    • 类型变量的限制
    • 自定义泛型方法
  • 后续介绍
    • JAVA 泛型意淫之旅(二)
    • JAVA 泛型意淫之旅(三)

泛型基础

Java 泛型(generics)是 JDK 5 中引入的一个新特性, 泛型提供了编译时的类型安全检测机制。该机制允许程序员在强类型程序设计语言中编写代码时,使用一些以后才指定的类型,在实例化时作为参数指明这些类型。

下面看一个简单的例子,如果我们需要创建一个只包含字符串的集合,没有泛型,我们会这样做

ArrayList strList = new ArrayList();
strList.add("a");
strList.add("b");
strList.add(1); 

即使在其中错误的插入了一个整型,依然可以顺利通过编译。若要取集合中的值,需要进行强制类型转换,

String str = (String)strList.get(2);

此时由于集合中第 3 个参数为整型,而非字符串型,在运行时会报出转换错误,

java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String

这样我们很难保证集合中的元素都是我们想要的类型。有了泛型之后,我们可以利用编译器的类型检测机制来帮助我们去发现类型是否合法。

ArrayList<String> strList2 = new ArrayList<>();
strList2.add("a");
strList2.add("b");
strList2.add(1);

同样的在集合中插入了一个整型的值,此时编译器会帮助我们发现,值 1 不是 String 类型,无法插入 strList2 集合,编译器会报出错误,

add(java.lang.String) in ArrayList cannot be applied to (int)

这样就很好的帮助我们避免了一些开发过程中可能出现的低级错误。

自定义泛型

自定义泛型类型

JAVA 本身为我们设计了一些泛型类型,如 ArrayList

以下我们以一个简单的例子演示一下如何自定义一个泛型类。假设我们现在有一个约会类 dating

public class Dating<T> {
    private T person;

    public Dating(){
        this.setPerson(null);
    }
    public Dating(T person){
        this.setPerson(person);
    }

    public T getPerson() {
        return person;
    }
    public void setPerson(T person) {
        this.person = person;
    }
}

T 为类型变量,用 <> 包裹,放在类名后面,这样我们可以在实例化 Dating 类的时候,给它传入合适的类型参数。如果是程序猿,我们可以限制只能传入女神类,如果是程序媛,我们可以限制只能传入男神类,没有彭于晏?我们自己 new 一个,没有贾静雯?我们有 new!

Dating<Man> dating = new Dating<>();
Man pengYuYan = new Man("彭于晏");
dating.setPerson(pengYuYan);

Dating<Woman> dating2 = new Dating<>();
Woman jiaJingWen = new Woman("贾静雯");
dating2.setPerson(jiaJingWen);

程序猿尝试约一下彭于晏?

dating2.setPerson(pengYuYan);

程序报错了:setPerson (Woman) in Dating cannot be applied to (Man),用中文翻译一下就是:性别不合。很好的杜绝了见面后发现对方也带棍的尴尬。

类型变量的限制

对于程序媛,约会几次后可能会从各方面考察对方是否符合自己的标准,首当其冲的是赚钱能力,如果对方无赚钱能力,只是个吃软饭的小白脸,则不会再有下次约会,可以对约会对象做一个限制,只有有赚钱能力的人才会和他有下次约会。

我们先定义一个接口

public interface MakeMoney {
    String makeMoney();
}

然后对 Dating 类的类型参数加一个限制

public class Dating<T extends MakeMoney> {
    private T person;
    ...
}

观察类名之后的 T 变为了 T extends MakeMoney, 此处限制了传入的类型,必须实现了 MakeMoney 接口,否则编译时则报错。(MakeMoeny 也可以是类,无论是类还是接口,都使用 extends 而不是 implements

我们的 Man 类型并没有实现 MakeMoney 接口,当将一个 Man 实例传入 dating 对象,则

Man toyBoy = new Man();
Dating dating = new Dating(toyBoy);

编译错误:Dating (MakeMoney) in Dating cannot be applied to (Man),翻译成中文就是:死开,小白脸!

自定义泛型方法

经过几次约会后,程序猿(程序媛)和女(男)神情意相投,决定结婚,下面新建一个婚礼类 Wedding,

public class Wedding {
    private Man bridegroom;
    private Woman bride;

    public Wedding(Man bridegroom, Woman bride) {
        this.bridegroom = bridegroom;
        this.bride = bride;
    }

    public Man getBridegroom() {
        return bridegroom;
    }

    public void setBridegroom(Man bridegroom) {
        this.bridegroom = bridegroom;
    }

    public Woman getBride() {
        return bride;
    }

    public void setBride(Woman bride) {
        this.bride = bride;
    }

    public <T> void receivingGift(T gift){
        System.out.println(gift);
    }
}

receivingGift 方法为一个泛型方法,可在调用方法时指定要传入的参数类型,同样的用 T 表示变量类型,用 <> 包裹,放在返回类型前。

婚礼最哈皮的莫过于收礼了,亲朋好友们一个个都很踊跃,有的送红包, 有的送超跑。

Man myself = new Man();
Woman jiaJingWen = new Woman();
Wedding wedding = new Wedding(myself,jiaJingWen);
wedding.<RedPacket>receivingGift(new RedPacket());
wedding.<Car>receivingGift(new Car());

以上为泛型方法的调用方式,在方法名前用 <> 包裹参数类型。来看一看执行结果:

OK, 整个意淫过程告一段落,成功迎娶白富美,走上人生巅峰!

后续介绍

JAVA 泛型意淫之旅(二)

  1. JVM 如何处理泛型
  2. 集合与泛型
  3. 泛型中的继承关系
  4. 泛型中的约束
  5. 泛型中的类型通配符
  6. 阿里巴巴泛型使用规范

JAVA 泛型意淫之旅(三)

  1. 常见面试题

原文地址:https://www.cnblogs.com/allen4tech/p/generic_type_1.html

时间: 2024-11-13 16:37:50

JAVA 泛型意淫之旅(一)的相关文章

Java泛型中的PECS原则

今天在写代码的时候使用到了这样一个方法签名: public void foo(Map<String, String> map); 在写这个参数的时候正好在想一些关于泛型的东西,于是: public void foo(Map<? extends String, ? extends String> map); 这两种写法有什么区别呢?记得以前和同学讨论过这个问题,但后来没有记下来,渐渐又淡忘了.今天又去翻了好多资料,总算找到一些可以参考的,赶紧记在这里方便以后温故知新啦.好了,言归正传

Java泛型的协变

在上篇<Java泛型的基本使用>这篇文章中遗留下面问题,即将子类型也能加入到父类型的泛型中.要实现这样的功能必须借助于协变. 实验准备 如今在上篇文章展示的Decorator类型的基础上,添加一些代码,如代码清单1所看到的. 代码清单1 /** * * 描 述:Exp2使用br/> * 作 者:jiaan.gja<br/> * 历 史: (版本号) 作者 时间 凝视 <br/> * @param itemList */ public void doDecorate

2017.4.5 Java 泛型

Java 泛型(generics)是 JDK 5 中引入的一个新特性, 泛型提供了编译时类型安全检测机制,该机制允许程序员在编译时检测到非法的类型. 泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数. 假定我们有这样一个需求:写一个排序方法,能够对整形数组.字符串数组甚至其他任何类型的数组进行排序,该如何实现? 答案是可以使用 Java 泛型. 使用 Java 泛型的概念,我们可以写一个泛型方法来对一个对象数组排序.然后,调用该泛型方法来对整型数组.浮点数数组.字符串数组等进行排

关于Java泛型的使用

在目前我遇到的java项目中,泛型应用的最多的就属集合了.当要从数据库取出多个对象或者说是多条记录时,往往都要使用集合,那么为什么这么使用,或者使用时有什么要注意的地方,请关注以下内容. 感谢Windstep. 原文链接:http://www.cnblogs.com/lwbqqyumidi/p/3837629.html 原文标题:Java总结篇系列:Java泛型 (我的第一篇水文,233)

java 泛型 窜讲

一.为什么使用泛型      复用性:泛型的本质就是参数化类型,因而使用编写的泛型代码可以被许多不同类型的对象所复用.      安全性:在对类型Object引用的参数操作时,往往需要进行显式的强制类型转换.这种强制类型转换需要在运行时才能被发现是否转换异常,通过引入泛型能将在运行时才能检查类型转换,提前到编译时期就能检查. 二.自定义泛型 java中自定义泛型分为三种:泛型类.泛型接口.泛型方法. 下面使用一个案例演示泛型类.泛型方法,泛型接口类似,所以不再演示. // 自定义泛型类publi

1月21日 - (转)Java 泛型

java泛型 什么是泛型? 泛型(Generic type 或者 generics)是对 Java 语言的类型系统的一种扩展,以支持创建可以按类型进行参数化的类.可以把类型参数看作是使用参数化类型时指定的类型的一个占位符,就像方法的形式参数是运行时传递的值的占位符一样. 可以在集合框架(Collection framework)中看到泛型的动机.例如,Map 类允许您向一个 Map 添加任意类的对象,即使最常见的情况是在给定映射(map)中保存某个特定类型(比如 String)的对象. 因为 M

Java泛型_上界extends_下界super

?Java泛型_上界extends_下界super ? 通配符类型 <? extends T> 表示类型的上界,表示参数化类型的可能是T或是T的子类 <? super T> 表示类型下界(Java Core中叫超类型限定),表示参数化类型是此类型(T)的超类型(父类型),直至Object 当使用 Upper Bound 通配符时 如下代码, /**  * 代码中通配符<?> 是 <? extends Object> 的简写  *  * @param list

C++泛型 &amp;&amp; Java泛型实现机制

C++泛型 C++泛型跟虚函数的运行时多态机制不同,泛型支持的静态多态,当类型信息可得的时候,利用编译期多态能够获得最大的效率和灵活性.当具体的类型信息不可得,就必须诉诸运行期多态了,即虚函数支持的动态多态. 对于C++泛型,每个实际类型都已被指明的泛型都会有独立的编码产生,也就是说list<int>和list<string>生成的是不同的代码,编译程序会在此时确保类型安全性.由于知道对象确切的类型,所以编译器进行代码生成的时候就不用运用RTTI,这使得泛型效率跟手动编码一样高.

java 泛型详解(普通泛型、 通配符、 泛型接口,泛型数组,泛型方法,泛型嵌套)

JDK1.5 令我们期待很久,可是当他发布的时候却更换版本号为5.0.这说明Java已经有大幅度的变化.本文将讲解JDK5.0支持的新功能-----Java的泛型. 1.Java泛型  其实Java的泛型就是创建一个用类型作为参数的类.就象我们写类的方法一样,方法是这样的method(String str1,String str2 ),方法中参数str1.str2的值是可变的.而泛型也是一样的,这样写class Java_Generics<K,V>,这里边的K和V就象方法中的参数str1和st