栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

JDK1.5后增加了泛型,那么为什么要有泛型呢?我们该如何自定义泛型结构呢?

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

JDK1.5后增加了泛型,那么为什么要有泛型呢?我们该如何自定义泛型结构呢?


大家好,我是卷心菜,可以叫我菜菜,大二学生一枚。本篇主要讲解java泛型的理解、集合中简单使用泛型、自定义泛型结构(包括类、接口、方法)。如果您看完文章有所收获,可以三连支持博主哦~,嘻嘻。


文章目录
  • 一、什么是泛型?
  • 二、泛型的概念
  • 三、为什么要设计泛型?
  • 四、自定义泛型结构
    • 1、自定义泛型类
    • 2、自定义泛型接口
    • 3、自定义泛型方法

一、什么是泛型?

通俗来讲,可以把泛型理解为带有标签的罐子,罐子贴着红糖的标签,就只能放红糖;罐子贴着白糖的标签,就只能放白糖,不可以乱放。用集合来解释,可以理解为:
list贴上了String的泛型标签,就只能添加String类型的数据;list1贴上了Integer的泛型标签,就只能添加Integer类型的数据;否则就会报错。


二、泛型的概念
  • 所谓泛型,就是允许在定义类、接口时通过一个标识表示类中某个属性的类
    型或者是某个方法的返回值及参数类型。这个类型参数将在使用时(例如,
    继承或实现这个接口,用这个类型声明变量、创建对象)确定(即传入实
    际的类型参数,也称为类型实参)。
  • 从JDK1.5以后,Java引入了“参数化类型(Parameterized type)”的概念,允许我们在创建集合时再指定集合元素的类型,比如:List,这表明该List只能保存字符串类型的对象。
  • JDK1.5改写了集合框架中的全部接口和类,为这些接口、类增加了泛型支持,
    从而可以在声明集合变量、创建集合对象时传入类型实参。
  • 简单的看一下List接口中的泛型
public interface List extends Collection {
    Iterator iterator();
     T[] toArray(T[] a);
    boolean add(E e);

三、为什么要设计泛型?

所以为什么要有泛型呢?直接用Object类型存储数据不香吗?

以集合为例,当我们不使用泛型时:

    public void test1() {
        List list = new ArrayList<>();
        list.add(123);
        list.add(456);
        list.add("789");
        for (Object o : list) {
            Integer item = (Integer) o;
            System.out.println(item);
        }
    }
 

运行结果:


当我们使用泛型时:

    public void test2() {
        List list = new ArrayList<>();
        list.add(123);
        list.add(456);
//        list.add("789");添加失败
        for (Integer integer : list) {
            System.out.println(integer);
        }
    }

我们可以发现,使用泛型后,当添加的数据类型不满足条件时,编译就会报错;在遍历集合时,还可以避免强制类型转换。


四、自定义泛型结构 1、自定义泛型类
public class Order {
    String orderName;
    int orderId;
    //类的内部结构就可以使用类的泛型
    T orderT;
    //构造器
    public Order(){
    	//泛型数组
      	T[] arr = (T[]) new Object[8];
    }
    public Order(String orderName,int orderId,T orderT){
        this.orderName = orderName;
        this.orderId = orderId;
        this.orderT = orderT;
    }
    //注意,下面的三个方法都不是泛型方法
    public T getOrderT(){
        return orderT;
    }
    public void setOrderT(T orderT){
        this.orderT = orderT;
    }
    @Override
    public String toString() {
        return "Order{" +
                "orderName='" + orderName + ''' +
                ", orderId=" + orderId +
                ", orderT=" + orderT +
                '}';
    }
}

需要注意的是:

  • 异常类不能声明为泛型:
  • 编译不通过:
  • 静态方法中不能使用泛型:因为是静态方法,即可以使用类来调用;当使用类来调用方法时,并不知道参数T指的是什么,所以不行。当使用对象调用方法时,通过构造器创建对象时,就已经指明了T是什么类型。

2、自定义泛型接口

由于类和接口没有很大的区别,所以为了文章的完整性,就继续以类来讲解泛型相关的知识:

class Father {
}
// 子类不保留父类的泛型
// 1)没有类型 擦除
class Son1 extends Father {// 等价于class Son extends Father{
}
// 2)具体类型
class Son2 extends Father {
}
// 子类保留父类的泛型
// 1)全部保留
class Son3 extends Father {
}
// 2)部分保留
class Son4 extends Father {
}
class Father {
}
// 子类不保留父类的泛型
// 1)没有类型 擦除
class Son extends Father{//等价于class Son extends Father{
}
// 2)具体类型
class Son2 extends Father {
}
// 子类保留父类的泛型
// 1)全部保留
class Son3 extends Father {
}
// 2)部分保留
class Son4 extends Father {
}

总结:

  • 泛型如果不指定,将被擦除,泛型对应的类型均按照Object处理,但不等价
    于Object。经验:泛型要使用一路都用。要不用,一路都不要用。
  • 如果泛型结构是一个接口或抽象类,则不可创建泛型类的对象。
  • 泛型的指定中不能使用基本数据类型,可以使用包装类替换。

3、自定义泛型方法
  • 方法,也可以被泛型化,不管此时定义在其中的类是不是泛型类。在泛型方法中可以定义泛型参数,此时,参数的类型就是传入数据的类型。
  • 泛型方法的格式:[访问权限] <泛型> 返回类型 方法名([泛型标识 参数名称]) 抛出的异常
	//这些都是泛型方法:
    public  void say(List list) { }

    public static  List copyFromArrayToList(E[] arr) {
       ArrayList list = new ArrayList<>();
       for (E e : arr)
           list.add(e);
       return list;
    }

感谢阅读,一起进步,嘻嘻~

转载请注明:文章转载自 www.mshxw.com
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号