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);
        }
    }
    
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

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