泛型

一、泛型技术的由来

泛型是从JDK 1.5开始出现的一种安全机制。之前的版本会有安全隐患出现,数据类型的问题,导致程序发生类型转换异常。所以,JDK 1.5开发出了泛型技术,解决程序中的安全问题。

二、泛型如何解决安全问题

泛型的出现,可以强制集合存储指定的数据类型,其它类型不允许存储。如果指定集合只能存储String,其他类型是存不进来的。

书写格式:通用格式 集合类<数据类型> 变量 = new 集合类<数据类型>();

  • 强制集合存储指定的数据类型,如果数据类型不符号要求,编译失败
  • 写泛型的时候,前后的类型一致
  • JDK7新特性,泛型前后自动匹配,后面的可以不写 , 空菱形语法

三、泛型的好处

  • 保证安全:将问题,由运行时期,提前到了编译时期
  • 简化书写,代码量减少
  • 使用泛型,避免了类型的强制转换

ArrayList<E> 源代码,E就是一个变量而已,在这个类的方法中,写了E,同一个变量。传递什么值,E就就是什么值,有点类似于C/C++的模板一样。

 ArrayList<String>  array =new ArrayList<String>();
//源代码中的E,就全部变成了,String

迭代器接口 Iterator<E>方法next()返回值也是E,如果迭代器中指定泛型是String类型,Iterator<String>.next()方法返回值,跟着变成了String类型

以后,如果你需要用一个类,发现类的右边写了一个尖括号<>写泛型了,指定具体的数据类型。当然,存储基本数据类型时,泛型需要写包装类。

基本数据类型 包装类
byte Byte
boolean Boolean
short Short
char Character
int Integer
long Long
float Float
double Double

四、泛型使用的demo

/*
 * 集合存储自定义对象,带泛型,迭代器获取
 * Person在之前的demo里面写过
 */
import java.util.*;
import cn.itcast.collection.Person;
public class GenericDemo1 {
    public static void main(String[] args) {
        //ArrayList存储Person
        ArrayList<Person> array = new ArrayList<Person>();
        array.add(new Person("a",10));
        array.add(new Person("b",11));
        array.add(new Person("c",12));
        
        //迭代器迭代集合,集合的泛型怎么写,迭代器跟随集合的泛型
        Iterator<Person> it = array.iterator();
        while(it.hasNext()){
            //it.next()返回值,就是泛型指定的Person,不用强转了
            Person p = it.next();
            System.out.println(p.getName()+"..."+p.getAge());
        }
    }
}

五、泛型类/方法/接口

1. 泛型类和方法

  • 泛型类:将泛型,定义在类上,如果类中的任何位置出现了个泛型,和类上的泛型是相同的。工厂类案例 E==定义了一个变量
  • 泛型方法:跟随类的泛型走的。定义泛型不跟着类的走的.在方法的声明上,在返回值类型之前,定义泛型,这个泛型属于方法自己,不属于类上的泛型
  • 静态泛型方法:不可以和类上的泛型相同,如果相同,出现静态不能访问非静态,自定义一个泛型,这个泛型只属于这个静态方法。静态方法的泛型,写在返回值类型前
import java.util.ArrayList;
/*
 * 自定义泛型类,和泛型方法
 */

class Generic<QQ>{
    //使用类泛型
    public void show(QQ q){
        System.out.println(q);
    }
  
    //函数自定义泛型<>泛型修饰符在返回类型之前
    public <TT> void function(TT t){
        System.out.println(t);
    }
  
    //内部静态方法,静态不能调用非静态
    public  static <HAHA> void method(HAHA h){
        System.out.println(h);
    }
}
public class GenericDemo3 {
    public static  void main(String[] args) {
        Generic<Integer> g = new Generic<Integer>();
        //show方法的参数,跟随泛型走,现在的参数类型是Integer类型
        g.show(100);
        //调用方法function,泛型可以任意传递
        g.function('a');
        
      //静态方法,类名调用,使用方法自定义泛型,不跟随类 ,也不允许跟随类
        Generic.method("随便传");
    }
}

2. 泛型接口

接口上定义泛型:

  • 实现类实现接口不指定泛型
  • 实现类实现接口的同时,就实现了泛型

demo:

/*
 * 自定义泛型接口,实现类实现接口,不指定泛型
 * 实现类实现接口的同时直接指定泛型
 */
interface Face<T>{
    public abstract void show(T t);
}

//定义实现类,实现接口,同时实现泛型
class FaceImpl2 implements Face<String>{
    public void show(String s ){
        System.out.println(s);
    }
}

//定义实现类,实现接口,不理会泛型,等待对象指定具体的数据类型
class FaceImpl<T> implements Face<T>{
    public void show(T t){
        System.out.println(t);
    }
}
public class GenericDemo4 {
    public static void main(String[] args) {
        FaceImpl<String> face = new FaceImpl<String>();
        FaceImpl<Integer> face1 = new FaceImpl<Integer>();
        face.show("随便传");
        
        FaceImpl2 face2 = new FaceImpl2();
        face2.show("只能是字符串");
    }
}

六、泛型的统配和限定

1. 泛型的通配符

传统文件系统中,通配符 * 匹配任意的文件名,或者是后缀名 del . del .java 等等。 假设定义方法,做集合的遍历,但是要求的是遍历任意的一个Collection下的子类集合,此时就要使用通配符。泛型中,通配符号?*问号,匹配所有的泛型类型,好处方便遍历集合,弊端在于不能进行强转。

demo

/*
 * 泛型的通配符
 */
import java.util.*;

public class GenericDemo1 {
    public static void main(String[] args) {
        List<String> list = new ArrayList<String>();
        list.add("asfd");
        list.add("adsfgsfd");
        list.add("sdfgsd");
        list.add("asertfd");
        list.add("qwey");
        method(list);
    }
    
    /*
     * 定义方法,遍历集合,但是不知道集合的类型
     * 使用  ? 泛型的通配符
     * 缺点:只能遍历。没办法做强转
     */
    public static void method(Collection<?> c){
        Iterator<?> it = c.iterator();
        while(it.hasNext()){
            System.out.println(it.next());
        }
    }
}

2. 泛型的限定

泛型的限定问题,写泛型的时候,只需要确定子类,或者父类就可以使用泛型的限定,案例员工和经理,实现了限定操作,提高了安全性,避免了数据类型的强制转换

泛型上限限定 ? extends E 传递E类型 和E的子类

泛型下限限定 ? super E 传递E类型 和E的父类

七、增强for循环

直接给出demo:

package generic;

import java.util.*;

/*
 * 练习增强for循环
 */
public class ForeachDemo {
    public static void main(String[] args) {

        method2();
    }

    /*
     * 普通数据类型的遍历
     */
    public static void method() {
        int[] a = { 6, 8, 8, 9, 10, 674, 687 };

        for (int i : a) {
            System.out.print(i + "  ");
        }

        System.out.println("");
        char[] b = { 's', 'd', 'f', 'l', 'i' };

        for (char i : b) {
            System.out.print(i);
        }
    }

    /*
     * 对象数组的遍历
     */
    public static void method1() {
        String[] s = { "saefsadf", "saasdf", "sadfasdfsdf" };

        for (String i : s) {
            System.out.println(i.length());
        }
    }

    /*
     * 集合的遍历
     */
    public static void method2() {
        Set<String> s = new HashSet<String>();
        s.add("sretgd");
        s.add("dfga");
        s.add("sretwrey5gd");
        s.add("sresdfgrtgd");
        s.add("rt78uj");
        for (String i : s) {
            System.out.println(i.length());
        }
    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,922评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,591评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,546评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,467评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,553评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,580评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,588评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,334评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,780评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,092评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,270评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,925评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,573评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,194评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,437评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,154评论 2 366
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,127评论 2 352

推荐阅读更多精彩内容

  • object 变量可指向任何类的实例,这让你能够创建可对任何数据类型进程处理的类。然而,这种方法存在几个严重的问题...
    CarlDonitz阅读 912评论 0 5
  • 1. 泛型概述 泛型(Generic type 或者 generics)是对 Java 语言的类型系统的一种扩展,...
    JackChen1024阅读 510评论 0 3
  • 第8章 泛型 通常情况的类和函数,我们只需要使用具体的类型即可:要么是基本类型,要么是自定义的类。但是在集合类的场...
    光剑书架上的书阅读 2,148评论 6 10
  • 有人一生长得在怎么气质整齐,也许还不是青春徒劳 看到看到的还就那样完去了! 看到 看到 可惜 可惜的 留不住的流逝...
    z01973阅读 181评论 0 2
  • 再见,2015。再见,迷茫。再见,金太阳。 时光荏苒,白驹过隙。转眼间,我已经在二字开头的年龄里又增长了一岁...
    爱度薛燕子阅读 608评论 0 0