java泛型学习笔记

本文章是个人学习笔记,如有错误欢迎指正

Java泛型

一、定义和存在意义

定义:允许程序员在强类型程序设计语言中编写代码时定义一些可变部分,那些部分在使用前必须作出指明,实质是:参数化类型

好处:

  • 类型安全
  • 消除强制类型转换

二、泛型类、接口

泛型类定义:

/**
 * 泛型类定义
 * @param <T> 泛型标识---类型形参,T在创建对象的时候指定具体的数据类型,
 *           由外部使用类来指定
 */
public class Generic<T> {
    private T key;

    public Generic(T key) {
        this.key = key;
    }

    public T getKey() {
        return key;
    }

    public void setKey(T key) {
        this.key = key;
    }
}

泛型类使用:

 Generic<String> stringGeneric=new Generic<>("泛型实参");

注意:

  • 若泛型类在创建对象时候没有指定类型,将视为object类型
  • 泛型类不支持基本数据类型,如int,必须使用Integer来指定
  • 同一泛型类根据不同数据类型创建的对象本质上是同一类型,getClass()相等,所以没法进行方法重载

从泛型类派生子类:

  • 父类是泛型类,子类也是,则要求子类和父类的泛型类型要一致,若继承时父类不指定,则默认Object类

    //父类
    public class Parent<E> {
        private  E key;
    
        public E getKey() {
            return key;
        }
    
        public void setKey(E key) {
            this.key = key;
        }
    }
    //第一种继承方式:
    class Child<T> extends Parent{
        @Override
        public Object getKey() {
            return super.getKey();
        }
    }
    //第二种继承方式:
    class  Child2<T> extends Parent<T>{
        @Override
        public T getKey() {
            return super.getKey();
        }
    }
    
  • 父类是泛型,子类不是,则要求父类必须明确泛型的数据类型,或者不指定默认Object

    public class Parent<E> {
        private  E key;
    
        public E getKey() {
            return key;
        }
    
        public void setKey(E key) {
            this.key = key;
        }
    }
    class Child3 extends Parent{
        @Override
        public Object getKey() {
            return super.getKey();
        }
    }
    class Child4 extends Parent<String>{
        @Override
        public String getKey() {
            return super.getKey();
        }
    }
    //编译出错
    class Child5 extends Parent<T>{
        @Override
        public Object getKey() {
            return super.getKey();
        }
    }
    

泛型接口定义:

public interface GenericInterface<T> {
    T getKey();
}

泛型接口的使用:

  • 实现接口的类是泛型类,则要求泛型类型一致

    public interface GenericInterface<T> {
        T getKey();
    }
    class Apple<T>implements GenericInterface<T>{
    
        @Override
        public T getKey() {
            return null;
        }
    }
    
  • 实现接口的类不是泛型类,则要求明确泛型的数据类型

    public interface GenericInterface<T> {
        T getKey();
    }
    
    class Organe implements GenericInterface<Integer>{
        @Override
        public Integer getKey() {
            return null;
        }
    }
    

泛型方法:

//例如: 
public <E> E get(ArrayList<E> list){
        return list.get(5);
    }

注:泛型方法也支持静态方法

二|类型通配符

类型通配符使用?代替类型实参,而不是形参

比如

定义泛型类:

class  Box<T>{
    ......
}

定义泛型方法:

注意:泛型类是无法进行泛型重载的

//编译错误
public void showBox(Box<String> box){
......
}
public void showBox(Box<Integer> box){
......
}

正确定义:

public void showBox(Box<?> box){
......
}

使用

Box<Integer> b1=new Box();
Box<String> b2=new Box();
showBox(b1);
showBox(b1);

类型通配符的上下限:

上限

//表明该泛型的类型只能是该实参类型,或者是该实参的子类类型
类/接口<? extends 实参类型>

下限

//表明该泛型的类型只能是该实参类型,或者是该实参的父类类型
类/接口<? super 实参类型>

三、类型擦除

泛型是jdk1.5引入的,但是泛型可以兼容之前的代码是由于:泛型只存在代码编译阶段,在进入jvm之前就已经将泛型相关信息擦除了。

  • 无限制类型擦除:对于无限制的泛型类型都将默认视为Object类型

  • 有限制类型擦除:对于有上限的泛型类型,将擦除为上限的类型

  • 桥接方法:对于泛型接口中的泛型类型都会默认视为Object类型,在其实现类中,会生成一个有指定类型的实现方法和一个Object类型的实现方法来保持类与接口的实现关系

    擦除之前:

    interface   Box<T>{
        T get(T key);
    }
    class BoxImpl implements  Box<Integer>{
    
        @Override
        public Integer get(Integer key) {
            return key;
        }
    }
    

    擦除之后:

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

推荐阅读更多精彩内容

  • 一.介绍 泛型在java中有很重要的地位,在面向对象编程及各种设计模式中有非常广泛的应用。 什么是泛型?为什么要使...
    走着别浪阅读 281评论 0 1
  • 所谓泛型,就是变量类型的参数化。泛型是java1.5中引入的一个重要特征,通过引入泛型,可以使编译时类型安全,运行...
    cvmars阅读 213评论 0 2
  • 为什么是object 我们都知道object是所有类的超类,那么在早期没有泛型概念的时候 其实就是用object来...
    金色888阅读 514评论 0 0
  • 泛型概述 Java泛型(generics)是JDK 5中引入的一个新特性,允许在定义类和接口的时候使用类型参数(t...
    billy_success阅读 438评论 0 1
  • 无论这个世界对你怎样 都请你一如既往的努力 人生是一场一个人的旅程无人可替代…你除了努力,勇敢,别无选择…让自己充...
    迷迭_e363阅读 222评论 0 3